@hydraharness/harness-base 0.1.1-rc.6

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 DeepSeek
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,26 @@
1
+ # `@hydraharness/harness-base`
2
+
3
+ The [media generation plugin](../../media/tool-media/README.md) mounts by default with one live Settings switch for image and video tools. Configure a generation model and its credentials before requesting media; mounting the plugin makes no provider request.
4
+
5
+ The shared hydra core as a profile bundle: [`cordis.patch.yml`](cordis.patch.yml) inserts every base plugin row — model adapters, the shared [`agent-default-model`](../../core/agent-default-model/README.md) selection, tools, persistence, policy, settings/credentials, telemetry, the [`imported OpenAI/Codex plugin runtime`](../../host/plugin-runtime/README.md), and the core spawn/fork subagent providers — over the empty profile root, as the first layer of every profile's `hydra.profile.bundles` list. The optional Codex and Claude Code providers stay outside this package and its production dependency closure; a Profile installs either [product provider Bundle](../../subagent/README.md) only when needed. The default `@hydraharness/harness` production closure therefore includes neither product provider, the Claude Agent SDK, nor the Codex wrapper and platform payloads. Later bundle layers (e.g. [`@hydraharness/harness-web-app`](../web-app/README.md)) and the user's profile `cordis.patch.yml` override these rows by id; a patch replaces a row's whole `config`, so mode-specific values live in mode bundles, not here. The package has no runtime API; the profile composer resolves the patch through the `hydra.bundle.patch` manifest field, never through code.
6
+
7
+ The patch gates both shell stacks by platform on its own rows: `bash-sandbox`/`tool-bash` carry `disabled: !!js process.platform === 'win32'` (bash has no Windows runner), and their twins `pwsh-sandbox`/`tool-pwsh` mount on win32 only with the inverted expression — one shared patch file, exactly one shell stack per host. The permission surface stays exactly as on POSIX: `sandbox`/`sandbox-policy` enforce the file-effect policy through the Windows ACL restricted-token runner (the win32 chain of `@hydraharness/harness-sandbox-local` → `@hydraharness/harness-sandbox-windows-acl`), the permission switcher and the approval service run unchanged, and `fs-sandbox` keeps fencing `ctx.fs` writes — mounting `@hydraharness/harness-fs-local` alongside it would double-register `ctx.fs` and fail the load. A Windows host that prefers the unconfined local pwsh executor or full access overrides these rows through its profile or home `cordis.patch.yml` (the bash-restore recipe must be complete: disable `pwsh-sandbox`/`tool-pwsh` AND re-enable `bash-sandbox`/`tool-bash` — both executor families register the same `bash` service, so an incomplete recipe fails loud at load). POSIX hosts see the pwsh rows disabled.
8
+
9
+ The row set and its rationale are documented inline in the patch file; the [generated composition graph](../../../apps/cli/composition.md) renders it.
10
+
11
+ The base bundle mounts DeepSeek, Serper, and Other search providers with [explicit Settings selection](../../web/web/README.md#product-search-settings) and public HTTP fetch. Standard and Code presets expose fetch; private origins require an explicit operator grant in the [HTTP provider](../../web/web-fetch-http/README.md). The optional [research policy](../../guard/research-policy/README.md) can impose deployment limits when configured explicitly.
12
+
13
+ The base also mounts the LSP capability; its stdio provider defaults to disabled unless `HYDRA_LSP_COMMAND` is set. The provider checks executable availability on query, so a saved enablement override or a command unavailable on another machine cannot prevent Desktop or Web startup. Install a compatible server on that host and set `HYDRA_LSP_COMMAND` to its command or absolute path; queries against a missing server return `LSP_UNAVAILABLE`. See [stdio configuration](../../lsp/lsp-stdio/README.md#configuration).
14
+
15
+ ## Model Experience
16
+
17
+ Indirectly, through the inserted rows: this bundle selects the shipped persona-less prompt base, tool set, and DeepSeek adapter that mode bundles specialize, and contributes no model-visible text of its own.
18
+
19
+ #### KV Cache effect
20
+
21
+ None directly; each inserted row's package owns its effect.
22
+
23
+ ## Known Limitations and Deferred Work
24
+
25
+ - **A patch replaces whole row configs** — profile overrides must restate every field a row keeps; there is no deep-merge layer.
26
+ - **The Windows temp grant is a private per-session subdirectory** — `workspace-write` confines writes to the workspace plus the session's own temp subdirectory (`<temp>\hydra-<hash>`, TMP/TEMP rewritten for confined children); `read-only` grants nothing. See `@hydraharness/harness-sandbox-windows-acl`.
@@ -0,0 +1,617 @@
1
+ # The hydra-base bundle patch: the shared core of every hydra profile, applied as
2
+ # ONE insert over the empty profile root. Later bundle patches and the user's
3
+ # profile cordis.patch.yml address these rows by id, with the last write
4
+ # winning per row.
5
+ #
6
+ # A patch replaces the targeted row's whole `config` rather than merging into
7
+ # it, so a row whose value differs by mode does NOT live here: it belongs to
8
+ # each mode bundle, keeping any single row down to one bundle layer plus the
9
+ # user's. Mode-specific rows appear below only with shared plugin identity and
10
+ # neutral defaults; each mode bundle restates its complete configuration.
11
+ #
12
+ # Row order carries no load semantics (activation is service-availability
13
+ # driven); the grouping is for readers.
14
+
15
+ - insert:
16
+ - id: timer
17
+ name: '@hydraharness/cordis-plugin-timer'
18
+ description: Schedules Cordis tasks and timers used by other plugins.
19
+ application: Run delayed and recurring Host work when a plugin registers a timer.
20
+ pluginType: core
21
+
22
+ - id: hmr
23
+ name: '@hydraharness/cordis-plugin-hmr'
24
+ description: Reloads changed plugin modules during development.
25
+ application: Apply local plugin edits without restarting the entire Host.
26
+ config:
27
+ root: ['.']
28
+
29
+ - id: llm
30
+ name: '@hydraharness/harness-llm'
31
+ pluginType: core
32
+
33
+ - id: session
34
+ name: '@hydraharness/harness-session'
35
+ pluginType: core
36
+
37
+ - id: typert
38
+ name: '@hydraharness/harness-typert-registry'
39
+ pluginType: core
40
+
41
+ - id: typert-loader
42
+ name: '@hydraharness/harness-typert-loader'
43
+ pluginType: core
44
+
45
+ - id: typert-gateway
46
+ name: '@hydraharness/harness-api-gateway'
47
+ pluginType: core
48
+
49
+ - id: session-title
50
+ name: '@hydraharness/harness-session-title'
51
+ pluginType: core
52
+ config:
53
+ fallbackMaxWords: 5
54
+ fallbackMaxBytes: 40
55
+ maxTitleBytes: 80
56
+
57
+ - id: session-title-llm
58
+ name: '@hydraharness/harness-session-title-first-prompt-llm'
59
+ config:
60
+ targetWords: 5
61
+ targetCjkCharacters: 10
62
+ maxInputBytes: 4096
63
+ maxOutputTokens: 64
64
+ timeoutMs: 60000
65
+
66
+ - id: user-questions
67
+ name: '@hydraharness/harness-user-questions'
68
+
69
+ - id: agent
70
+ name: '@hydraharness/harness-agent'
71
+ pluginType: core
72
+
73
+ # The transport-independent default for Agents created by entry points.
74
+ # Settings may supply a saved selection; consumers read it at creation time.
75
+ - id: agent-default-model
76
+ name: '@hydraharness/harness-agent-default-model'
77
+ pluginType: core
78
+ config:
79
+ provider: deepseek-official
80
+ model: deepseek-v4-flash
81
+
82
+ - id: jobs
83
+ name: '@hydraharness/harness-jobs-local'
84
+ pluginType: core
85
+
86
+ - id: llm-retry
87
+ name: '@hydraharness/harness-llm-retry'
88
+
89
+ - id: llm-call-log
90
+ name: '@hydraharness/harness-llm-call-log'
91
+
92
+ # User-settings document (`$HYDRA_HOME/settings.yaml`, hot-reloaded): a
93
+ # `llm-deepseek:` or `llm-pi-ai:` section there overrides the adapter entries
94
+ # below without a restart, and is what the web Models page writes.
95
+ - id: settings
96
+ name: '@hydraharness/harness-settings-file'
97
+ pluginType: core
98
+
99
+ # Credential sources: inherited environment over the managed
100
+ # `$HYDRA_HOME/.credentials.yaml`, with project and user `.env` fallbacks.
101
+ # Adapters resolve references per request; the Models page writes only the
102
+ # managed document, which is never materialized into the process environment.
103
+ - id: credentials
104
+ name: '@hydraharness/harness-credentials-local'
105
+ pluginType: core
106
+
107
+ # Provider-owned login flows use the shared credential record store and
108
+ # expose browser-safe notices/prompts through the Host authorization API.
109
+ - id: authorization
110
+ name: '@hydraharness/harness-authorization'
111
+ pluginType: core
112
+
113
+ # The pi-ai multi-provider twin, mounted dormant: zero routes (and no extra
114
+ # models in the picker) until a `llm-pi-ai:` settings section supplies provider
115
+ # profiles — then those routes register live, keys resolving per request
116
+ # through their apiKeyEnv references, and drop again when the section empties.
117
+ # Supplying those profiles is exactly what the web Models page does. Which
118
+ # adapters exist is composition; which providers run is the user's settings
119
+ # document.
120
+ - id: llm-pi-ai
121
+ name: '@hydraharness/harness-llm-pi-ai'
122
+ pluginType: core
123
+
124
+ # Account SDKs load only for login or requests on an enabled account route.
125
+ - id: llm-account-auth
126
+ name: '@hydraharness/harness-llm-account-auth'
127
+ pluginType: core
128
+
129
+ - id: session-persistence-jsonl
130
+ name: '@hydraharness/harness-session-persistence-jsonl'
131
+ pluginType: core
132
+ config:
133
+ root: !!js hydraHomePath('sessions')
134
+
135
+ # Durable image bytes live outside the append-only session log. Messages
136
+ # keep content-addressed references that this shared backend resolves for
137
+ # provider requests and authorized history reads.
138
+ - id: attachment-local
139
+ name: '@hydraharness/harness-attachment-local'
140
+
141
+ # Full-text session search is opt-in. `openAt: never` keeps
142
+ # ctx.sessionQuery mounted — exact reads, titles, and lineage traces
143
+ # (session export, subagent-fork Workspace inheritance) stay available —
144
+ # while search calls fail with SESSION_QUERY_SEARCH_DISABLED and SQLite is
145
+ # never opened; the Web sidebar search matches titles and workspace names
146
+ # only. Deployments enabling content search override `openAt` to
147
+ # `first-search` or `startup` in a later patch layer (profile
148
+ # cordis.patch.yml or a --patch overlay), typically with a durable `path`.
149
+ - id: session-query-sqlite
150
+ name: '@hydraharness/harness-session-query-sqlite'
151
+ config:
152
+ path: ':memory:'
153
+ openAt: never
154
+
155
+ # Shared projection registry: subagent catalog identity (mode/label) folds
156
+ # through its registered units, so the `list_agents` surface below fails
157
+ # loud without it; web layers reuse this same mount for list rows.
158
+ - id: session-projection
159
+ name: '@hydraharness/harness-session-projection'
160
+ pluginType: core
161
+
162
+ # Session telemetry is mounted but disabled by default. HYDRA_TELEMETRY_MODE
163
+ # explicitly opts into FULL or FEEDBACK_ONLY reporting; uploading mirrors
164
+ # session-log records onto OTLP/HTTP logs with no session-telemetry/record redaction
165
+ # rule, so exports are the raw captured copy. The deployment stance, env
166
+ # seams, and follow-ups are pinned in the default-off Agent Note.
167
+ # HYDRA_TELEMETRY_OTLP_URL overrides the production endpoint. A non-empty
168
+ # HYDRA_TELEMETRY_DISABLED — any value, including '0'/'false' — opts the
169
+ # process out (the launchers patch the row disabled; config cannot disable
170
+ # a row). Exports carry the harness home's anonymous user id ($HYDRA_HOME/.anonymous-user-id,
171
+ # random UUID; delete the file to reset the identity) as the Resource's
172
+ # user.id. The exporter/processor values normally bound the shutdown drain
173
+ # to ~1s against an unreachable collector: exporter.timeoutMillis is both
174
+ # the per-attempt socket timeout and the retry deadline (1s effectively
175
+ # disables the SDK's 5-try backoff), while maxExportBatchSize == maxQueueSize
176
+ # (both explicit) makes the drain a single batch. The SDK awaits
177
+ # exporter.forceFlush() outside exportTimeoutMillis, so the backend's 3s
178
+ # shutdownTimeoutMillis is the load-bearing outer bound when a transport
179
+ # promise never settles. Every CLI exit path drains it by disposing the root
180
+ # on SIGINT/SIGTERM.
181
+ - id: session-telemetry-otel
182
+ name: '@hydraharness/harness-session-telemetry-otel'
183
+ config:
184
+ mode: !!js process.env.HYDRA_TELEMETRY_MODE || 'DISABLED'
185
+ shutdownTimeoutMillis: 3000
186
+ exporter:
187
+ url: !!js process.env.HYDRA_TELEMETRY_OTLP_URL ?? 'https://harness-telemetry.deepseeksvc.com/v1/logs'
188
+ compression: gzip
189
+ timeoutMillis: 1000
190
+ processor:
191
+ scheduledDelayMillis: 10000
192
+ maxQueueSize: 2048
193
+ maxExportBatchSize: 2048
194
+ exportTimeoutMillis: 1500
195
+
196
+ - id: subprocess
197
+ name: '@hydraharness/harness-subprocess-local'
198
+ pluginType: core
199
+
200
+ # HYDRA_LSP_COMMAND enables semantic navigation for coding presets. Resolve
201
+ # the executable on query so a saved enablement override cannot block
202
+ # startup on a machine without the configured server.
203
+ - id: lsp
204
+ name: '@hydraharness/harness-lsp'
205
+ pluginType: core
206
+
207
+ - id: lsp-stdio
208
+ name: '@hydraharness/harness-lsp-stdio'
209
+ pluginType: core
210
+ disabled: !!js process.env.HYDRA_LSP_COMMAND === undefined
211
+ config:
212
+ servers:
213
+ typescript:
214
+ command: !!js process.env.HYDRA_LSP_COMMAND ?? 'typescript-language-server'
215
+ resolveAt: query
216
+ args: ['--stdio']
217
+ extensionToLanguage:
218
+ .ts: typescript
219
+ .tsx: typescriptreact
220
+ .js: javascript
221
+ .jsx: javascriptreact
222
+
223
+ # Every shipped CLI mode starts with the same file-effect boundary.
224
+ # The environment remains an explicit deployment override; otherwise fresh
225
+ # sessions pin workspace-write + ask through the permission service below.
226
+ - id: sandbox
227
+ name: '@hydraharness/harness-sandbox-local'
228
+ pluginType: core
229
+
230
+ - id: sandbox-policy
231
+ name: '@hydraharness/harness-sandbox-policy'
232
+ pluginType: core
233
+ config:
234
+ mode: !!js process.env.HYDRA_PERMISSION_MODE ?? 'workspace-write'
235
+ workspaceRoot: !!js process.cwd()
236
+
237
+ - id: bash-sandbox
238
+ name: '@hydraharness/harness-bash-sandbox'
239
+ pluginType: core
240
+ disabled: !!js process.platform === 'win32'
241
+ config:
242
+ timeoutMs: 60000
243
+
244
+ - id: pwsh-sandbox
245
+ name: '@hydraharness/harness-pwsh-sandbox'
246
+ pluginType: core
247
+ disabled: !!js process.platform !== 'win32'
248
+
249
+ - id: approval
250
+ name: '@hydraharness/harness-user-approval'
251
+ pluginType: core
252
+ config:
253
+ policy: !!js "(process.env.HYDRA_PERMISSION_MODE ?? 'workspace-write') === 'danger-full-access' ? 'never' : 'ask'"
254
+
255
+ - id: permission
256
+ name: '@hydraharness/harness-permission-presets'
257
+ pluginType: core
258
+ config:
259
+ presets:
260
+ read-only:
261
+ sandbox: read-only
262
+ approval: ask
263
+ workspace-write:
264
+ sandbox: workspace-write
265
+ approval: ask
266
+ danger-full-access:
267
+ sandbox: danger-full-access
268
+ approval: never
269
+
270
+ - id: shell-env
271
+ name: '@hydraharness/harness-shell-env'
272
+ pluginType: core
273
+
274
+ - id: tool-bash
275
+ name: '@hydraharness/harness-tool-bash'
276
+ disabled: !!js process.platform === 'win32'
277
+
278
+ - id: tool-pwsh
279
+ name: '@hydraharness/harness-tool-pwsh'
280
+ disabled: !!js process.platform !== 'win32'
281
+
282
+ - id: tool-jobs
283
+ name: '@hydraharness/harness-tool-jobs'
284
+
285
+ - id: fs-observation-policy
286
+ name: '@hydraharness/harness-fs-observation-policy'
287
+ pluginType: core
288
+
289
+ - id: tool-fs
290
+ name: '@hydraharness/harness-tool-fs'
291
+
292
+ - id: fs-review
293
+ name: '@hydraharness/harness-fs-review'
294
+
295
+ - id: tool-fs-search
296
+ name: '@hydraharness/harness-tool-fs-search'
297
+ config:
298
+ sampleOverCapGlobResults: false
299
+
300
+ - id: agent-instructions
301
+ name: '@hydraharness/harness-agent-instructions'
302
+ config:
303
+ maxBytes: 65536
304
+
305
+ # Personality preference: settings-backed tone selector for the system
306
+ # prompt, logged to each session as durable prompt provenance.
307
+ - id: personalization
308
+ name: '@hydraharness/harness-personalization'
309
+
310
+ - id: skill
311
+ name: '@hydraharness/harness-skill'
312
+ pluginType: core
313
+
314
+ - id: skill-filesystem
315
+ name: '@hydraharness/harness-skill-filesystem'
316
+
317
+ - id: skill-badge
318
+ name: '@hydraharness/harness-skill-badge'
319
+ disabled: true
320
+
321
+ - id: tool-skill
322
+ name: '@hydraharness/harness-tool-skill'
323
+
324
+ - id: commands
325
+ name: '@hydraharness/harness-commands'
326
+ pluginType: core
327
+
328
+ # Imported OpenAI/Codex plugin bundles are shared by every profile. The
329
+ # runtime owns immutable bundles, per-plugin data, and reversible loading.
330
+ - id: plugin-runtime
331
+ name: '@hydraharness/harness-plugin-runtime'
332
+ pluginType: core
333
+
334
+ # The user's own MCP servers and hooks, stored in `$HYDRA_HOME/settings.yaml`
335
+ # rather than composed here: each registry mounts what its settings section
336
+ # declares and unmounts it again when the record is disabled or removed, so
337
+ # a server or hook added from the Settings page survives a restart and one
338
+ # added by hand-editing the document takes effect without one.
339
+ - id: mcp-registry
340
+ name: '@hydraharness/harness-mcp-registry'
341
+ pluginType: core
342
+
343
+ - id: hooks-registry
344
+ name: '@hydraharness/harness-hooks-registry'
345
+ pluginType: core
346
+
347
+ - id: command-feedback
348
+ name: '@hydraharness/harness-command-feedback'
349
+
350
+ - id: goal
351
+ name: '@hydraharness/harness-goal'
352
+ pluginType: core
353
+
354
+ - id: goal-round-driver
355
+ name: '@hydraharness/harness-goal-round-driver'
356
+
357
+ - id: command-goal
358
+ name: '@hydraharness/harness-command-goal'
359
+
360
+ - id: plan-mode
361
+ name: '@hydraharness/harness-plan-mode'
362
+ config:
363
+ section: |
364
+ You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
365
+
366
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
367
+
368
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed only to keep the request shape stable. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
369
+
370
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
371
+
372
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
373
+
374
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
375
+
376
+ - id: token-meter
377
+ name: '@hydraharness/harness-token-meter'
378
+ pluginType: core
379
+
380
+ - id: compaction-basic
381
+ name: '@hydraharness/harness-compaction-basic'
382
+
383
+ # Human `/compact`: one useful reduction below the automatic threshold. Backend
384
+ # independent, so it follows whichever compaction service this leaf mounts.
385
+ - id: command-compact
386
+ name: '@hydraharness/harness-command-compact'
387
+
388
+ - id: subagent
389
+ name: '@hydraharness/harness-subagent'
390
+ config:
391
+ maxActivePerTree: 4
392
+ maxChildrenPerTree: 8
393
+ pluginType: core
394
+
395
+ - id: subagent-spawn-in-process
396
+ name: '@hydraharness/harness-subagent-spawn-in-process'
397
+ pluginType: core
398
+ config:
399
+ providerName: spawn
400
+
401
+ - id: subagent-fork-in-process
402
+ name: '@hydraharness/harness-subagent-fork-in-process'
403
+ pluginType: core
404
+ config:
405
+ providerName: fork
406
+
407
+ # Continuable background children are selected per delegation tool. The
408
+ # separately loaded follow-up tool registers the one global `send_message`.
409
+ - id: tool-subagent-control
410
+ name: '@hydraharness/harness-tool-subagent-control'
411
+
412
+ - id: tool-subagent-list-agents
413
+ name: '@hydraharness/harness-tool-subagent-control/list-agents'
414
+
415
+ - id: tool-subagent
416
+ name: '@hydraharness/harness-tool-subagent'
417
+ config:
418
+ provider: spawn
419
+ toolName: subagent
420
+ backgroundMode: continuable
421
+
422
+ # Fork stays one-shot: a continuable child's `report` tool and prompt
423
+ # section precede the inherited history a fork exists to reuse; one-shot
424
+ # fork children install neither, keeping the parent's request prefix.
425
+ # See .agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md.
426
+ - id: tool-subagent-fork
427
+ name: '@hydraharness/harness-tool-subagent'
428
+ config:
429
+ provider: fork
430
+ toolName: subagent_fork
431
+ backgroundMode: one-shot
432
+
433
+ # Optional direct-child return channel; absent from roots and one-shot agents.
434
+ - id: tool-subagent-report
435
+ name: '@hydraharness/harness-tool-subagent-report'
436
+
437
+ - id: workflow-worker-thread
438
+ name: '@hydraharness/harness-workflow-worker-thread'
439
+ config:
440
+ provider: spawn
441
+
442
+ - id: tool-workflow
443
+ name: '@hydraharness/harness-tool-workflow'
444
+
445
+ - id: timeout-policy
446
+ name: '@hydraharness/harness-tool-call-timeout-policy'
447
+
448
+ - id: spill-local
449
+ name: '@hydraharness/harness-spill-local'
450
+ pluginType: core
451
+
452
+ - id: spill-policy
453
+ name: '@hydraharness/harness-spill-policy'
454
+ pluginType: core
455
+ config:
456
+ maxInlineBytes: 50000
457
+
458
+ # Durability checkpoints before each model request and top-level dispatch.
459
+ - id: session-checkpoint-policy
460
+ name: '@hydraharness/harness-session-checkpoint-policy'
461
+ pluginType: core
462
+
463
+ # Compacts oversized tool results before the broader conversation compactor
464
+ # runs, preserving the model-visible result within the configured budget.
465
+ - id: tool-result-pruner
466
+ name: '@hydraharness/harness-compaction-tool-result-pruner'
467
+ config:
468
+ thresholdChars: 8192
469
+ headChars: 4096
470
+ tailChars: 1024
471
+
472
+ - id: tool-media
473
+ name: '@hydraharness/harness-tool-media'
474
+
475
+ - id: tool-session-version
476
+ name: '@hydraharness/harness-tool-session-version'
477
+
478
+ - id: tool-todo
479
+ name: '@hydraharness/harness-tool-todo'
480
+ config:
481
+ allowParallelInProgress: true
482
+
483
+ # Persisted same-session goals reach the model and the slash menu here; the
484
+ # domain, driver, and `/goal` command are above.
485
+ - id: tool-goal
486
+ name: '@hydraharness/harness-tool-goal'
487
+
488
+ # Fresh-agent Ralph iteration over a build-time-fixed script.
489
+ - id: tool-ralph
490
+ name: '@hydraharness/harness-tool-ralph'
491
+ config:
492
+ subagentProvider: spawn
493
+ maxRounds: 64
494
+
495
+ - id: tool-str-replace-editor
496
+ name: '@hydraharness/harness-tool-str-replace-editor'
497
+ config:
498
+ maxOutputChars: 16000
499
+
500
+ # Consecutive-repeat reminders on the tool chain.
501
+ - id: repeat-tool-reminder
502
+ name: '@hydraharness/harness-repeat-tool-reminder'
503
+ config:
504
+ thresholds: [3, 5, 8]
505
+ argumentsPreviewChars: 500
506
+
507
+ # Every mode enables the stable model-facing web_search tool. Search provider
508
+ # selection is saved independently of the active chat model in Settings.
509
+ - id: research-policy
510
+ name: '@hydraharness/harness-research-policy'
511
+
512
+ - id: web
513
+ name: '@hydraharness/harness-web'
514
+ pluginType: core
515
+ config:
516
+ requireSearchSelection: true
517
+
518
+ - id: web-search-deepseek
519
+ name: '@hydraharness/harness-web-search-deepseek'
520
+ pluginType: core
521
+
522
+ - id: web-search-http
523
+ name: '@hydraharness/harness-web-search-http'
524
+ pluginType: core
525
+
526
+ - id: web-fetch-http
527
+ name: '@hydraharness/harness-web-fetch-http'
528
+ pluginType: core
529
+ config:
530
+ timeoutMs: 45000
531
+
532
+ - id: tool-web
533
+ name: '@hydraharness/harness-tool-web'
534
+ config:
535
+ fetch: true
536
+ searchTimeoutMs: 60000
537
+
538
+ # The embedded browser seam. It starts no Electron process until an agent's
539
+ # first browser action, so mounting it here costs nothing in a session that
540
+ # never browses; without the optional `electron` package every call fails
541
+ # with BROWSER_UNAVAILABLE and the rest of the harness is unaffected. The
542
+ # profile directory persists so an SSO login survives the session — and
543
+ # carries the prompt-injection exposure the package README documents.
544
+ - id: browser-electron
545
+ name: '@hydraharness/harness-browser-electron'
546
+ pluginType: core
547
+
548
+ # Recalls graph-linked Obsidian knowledge through MCP, plus approval-gated
549
+ # knowledge saves. Independent of Browser tooling.
550
+ - id: obsidian-knowledge
551
+ name: '@hydraharness/harness-obsidian-knowledge'
552
+
553
+ # Verified per-page task guidance in private SQLite, scoped to this
554
+ # workspace. Dormant by default: a role is an operator's own vocabulary
555
+ # for their deployment (order-operator, support-agent, ...), so there is
556
+ # no neutral default to mount unconditionally. Setting HYDRA_PAGE_MEMORY_ROLE
557
+ # opts in; Settings → Plugins overrides role/locale/storageDir afterward,
558
+ # taking effect after a restart.
559
+ - id: page-memory
560
+ name: '@hydraharness/harness-page-memory'
561
+ disabled: !!js process.env.HYDRA_PAGE_MEMORY_ROLE === undefined
562
+ config:
563
+ workspaceDir: !!js process.cwd()
564
+ role: !!js process.env.HYDRA_PAGE_MEMORY_ROLE ?? ''
565
+ locale: !!js process.env.HYDRA_PAGE_MEMORY_LOCALE ?? 'en-US'
566
+
567
+ # ── rows every mode mounts, whose values each overlay may state ──────────────
568
+
569
+ # The tool registry. Presentation mode is a deployment choice; omitting it here
570
+ # keeps the schema default (native).
571
+ - id: tools
572
+ name: '@hydraharness/harness-tools'
573
+ pluginType: core
574
+
575
+ # The deployment persona is a deployment choice; plan-mode and tool plugins own
576
+ # their own prompt sections.
577
+ - id: system-prompt
578
+ name: '@hydraharness/harness-system-prompt'
579
+ pluginType: core
580
+ config:
581
+ persona: ''
582
+
583
+ # Agents created at startup. The base stays empty; raw overlays may create
584
+ # agents, while Web creates sessions on client request.
585
+ - id: agent-loop
586
+ name: '@hydraharness/harness-agent-loop'
587
+ pluginType: core
588
+ config:
589
+ agents: []
590
+
591
+ # The sandboxed filesystem provider. `cwd` defaults to `process.cwd()`; an
592
+ # overlay can pin another workspace.
593
+ - id: fs-sandbox
594
+ name: '@hydraharness/harness-fs-sandbox'
595
+ pluginType: core
596
+
597
+ # The native DeepSeek adapter. No key or endpoint is inlined: both resolve per
598
+ # request from the `llm-deepseek:` settings section over this entry, with the
599
+ # key coming from the credential store below. Thinking defaults are a deployment
600
+ # choice.
601
+ - id: llm-deepseek
602
+ name: '@hydraharness/harness-llm-deepseek'
603
+ pluginType: core
604
+
605
+ # Optional TypeSafe Jev decision capability. It is dormant by default;
606
+ # enabling it never changes the LLM provider catalog.
607
+ - id: jev
608
+ name: '@hydraharness/harness-jev'
609
+ pluginGroup: jev
610
+ disabled: true
611
+
612
+ # Jev's bounded consumer: the model may ask for a candidate browser-action
613
+ # decision, while the existing browser executor retains authority.
614
+ - id: browser-decisions
615
+ name: '@hydraharness/harness-browser-decisions'
616
+ pluginGroup: jev
617
+ disabled: true
package/lib/index.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@hydraharness/harness-base`.
4
+ * @module @hydraharness/harness-base/invariant
5
+ */
6
+ const PACKAGE_NAME = "@hydraharness/harness-base";
7
+ /** Cordis companion plugin name. */
8
+ const name = "base-bundle-invariant";
9
+ /** Service required before the companion can register. */
10
+ const inject = ["invariants"];
11
+ const install = () => {};
12
+ /**
13
+ * Register this package's invariant companion.
14
+ * @param ctx - Cordis context carrying the invariant service.
15
+ * @returns the installed registration's disposer after setup succeeds.
16
+ */
17
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
18
+ //#endregion
19
+ export { apply, inject, name };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @hydraharness/harness-base — the shared hydra core as a profile bundle. The
3
+ * package's substance is `cordis.patch.yml`, declared by the `hydra.bundle.patch`
4
+ * manifest field and resolved by the profile composer through that field;
5
+ * this module carries no runtime API.
6
+ * @module @hydraharness/harness-base
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@hydraharness/harness-base`.
3
+ * @module @hydraharness/harness-base/invariant
4
+ */
5
+ import type { Context } from '@hydraharness/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "base-bundle-invariant";
8
+ /** Service required before the companion can register. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
package/package.json ADDED
@@ -0,0 +1,152 @@
1
+ {
2
+ "name": "@hydraharness/harness-base",
3
+ "description": "The shared hydra core as a profile bundle: every profile's first patch layer, inserting the base plugin rows over the empty profile root",
4
+ "version": "0.1.1-rc.6",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/MaiHongPhong1902/Hydra-Harness.git",
11
+ "directory": "packages/bundle/base"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./cordis.patch.yml": "./cordis.patch.yml",
26
+ "./src/*": "./src/*",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "files": [
30
+ "lib/index.js",
31
+ "lib/invariant.js",
32
+ "cordis.patch.yml",
33
+ "lib/types/**/*.d.ts"
34
+ ],
35
+ "license": "MIT",
36
+ "hydra": {
37
+ "bundle": {
38
+ "patch": "./cordis.patch.yml"
39
+ }
40
+ },
41
+ "dependencies": {
42
+ "@hydraharness/cordis-plugin-hmr": "^1.0.17",
43
+ "@hydraharness/cordis-plugin-timer": "^1.1.4",
44
+ "@hydraharness/harness-agent": "^0.1.1-rc.6",
45
+ "@hydraharness/harness-agent-default-model": "^0.1.1-rc.6",
46
+ "@hydraharness/harness-agent-loop": "^0.1.1-rc.6",
47
+ "@hydraharness/harness-agent-instructions": "^0.1.1-rc.6",
48
+ "@hydraharness/harness-api-gateway": "^0.1.1-rc.6",
49
+ "@hydraharness/harness-attachment-local": "^0.1.1-rc.6",
50
+ "@hydraharness/harness-authorization": "^0.1.1-rc.6",
51
+ "@hydraharness/harness-bash-sandbox": "^0.1.1-rc.6",
52
+ "@hydraharness/harness-browser-decisions": "^0.1.1-rc.6",
53
+ "@hydraharness/harness-browser-electron": "^0.1.1-rc.6",
54
+ "@hydraharness/harness-command-compact": "^0.1.1-rc.6",
55
+ "@hydraharness/harness-command-feedback": "^0.1.1-rc.6",
56
+ "@hydraharness/harness-command-goal": "^0.1.1-rc.6",
57
+ "@hydraharness/harness-commands": "^0.1.1-rc.6",
58
+ "@hydraharness/harness-compaction-basic": "^0.1.1-rc.6",
59
+ "@hydraharness/harness-compaction-tool-result-pruner": "^0.1.1-rc.6",
60
+ "@hydraharness/harness-fs-local": "^0.1.1-rc.6",
61
+ "@hydraharness/harness-credentials-local": "^0.1.1-rc.6",
62
+ "@hydraharness/harness-fs-review": "^0.1.1-rc.6",
63
+ "@hydraharness/harness-fs-observation-policy": "^0.1.1-rc.6",
64
+ "@hydraharness/harness-fs-sandbox": "^0.1.1-rc.6",
65
+ "@hydraharness/harness-goal": "^0.1.1-rc.6",
66
+ "@hydraharness/harness-hook-protocol": "^0.1.1-rc.6",
67
+ "@hydraharness/harness-goal-round-driver": "^0.1.1-rc.6",
68
+ "@hydraharness/harness-hooks-registry": "^0.1.1-rc.6",
69
+ "@hydraharness/harness-hooks-codex": "^0.1.1-rc.6",
70
+ "@hydraharness/harness-jev": "^0.1.1-rc.6",
71
+ "@hydraharness/harness-jobs-local": "^0.1.1-rc.6",
72
+ "@hydraharness/harness-llm": "^0.1.1-rc.6",
73
+ "@hydraharness/harness-llm-account-auth": "^0.1.1-rc.6",
74
+ "@hydraharness/harness-llm-call-log": "^0.1.1-rc.6",
75
+ "@hydraharness/harness-llm-deepseek": "^0.1.1-rc.6",
76
+ "@hydraharness/harness-llm-pi-ai": "^0.1.1-rc.6",
77
+ "@hydraharness/harness-llm-retry": "^0.1.1-rc.6",
78
+ "@hydraharness/harness-lsp": "^0.1.1-rc.6",
79
+ "@hydraharness/harness-lsp-stdio": "^0.1.1-rc.6",
80
+ "@hydraharness/harness-mcp-client": "^0.1.1-rc.6",
81
+ "@hydraharness/harness-mcp-registry": "^0.1.1-rc.6",
82
+ "@hydraharness/harness-obsidian-knowledge": "^0.1.1-rc.6",
83
+ "@hydraharness/harness-permission-presets": "^0.1.1-rc.6",
84
+ "@hydraharness/harness-page-memory": "^0.1.1-rc.6",
85
+ "@hydraharness/harness-plan-mode": "^0.1.1-rc.6",
86
+ "@hydraharness/harness-personalization": "^0.1.1-rc.6",
87
+ "@hydraharness/harness-plugin-runtime": "^0.1.1-rc.6",
88
+ "@hydraharness/harness-pwsh-sandbox": "^0.1.1-rc.6",
89
+ "@hydraharness/harness-repeat-tool-reminder": "^0.1.1-rc.6",
90
+ "@hydraharness/harness-sandbox-local": "^0.1.1-rc.6",
91
+ "@hydraharness/harness-research-policy": "^0.1.1-rc.6",
92
+ "@hydraharness/harness-sandbox-policy": "^0.1.1-rc.6",
93
+ "@hydraharness/harness-session": "^0.1.1-rc.6",
94
+ "@hydraharness/harness-session-checkpoint-policy": "^0.1.1-rc.6",
95
+ "@hydraharness/harness-session-persistence-jsonl": "^0.1.1-rc.6",
96
+ "@hydraharness/harness-session-projection": "^0.1.1-rc.6",
97
+ "@hydraharness/harness-session-query-sqlite": "^0.1.1-rc.6",
98
+ "@hydraharness/harness-session-telemetry-otel": "^0.1.1-rc.6",
99
+ "@hydraharness/harness-session-title": "^0.1.1-rc.6",
100
+ "@hydraharness/harness-session-title-first-prompt-llm": "^0.1.1-rc.6",
101
+ "@hydraharness/harness-settings-file": "^0.1.1-rc.6",
102
+ "@hydraharness/harness-skill-badge": "^0.1.1-rc.6",
103
+ "@hydraharness/harness-shell-env": "^0.1.1-rc.6",
104
+ "@hydraharness/harness-skill": "^0.1.1-rc.6",
105
+ "@hydraharness/harness-skill-filesystem": "^0.1.1-rc.6",
106
+ "@hydraharness/harness-spill-local": "^0.1.1-rc.6",
107
+ "@hydraharness/harness-subagent": "^0.1.1-rc.6",
108
+ "@hydraharness/harness-spill-policy": "^0.1.1-rc.6",
109
+ "@hydraharness/harness-subagent-fork-in-process": "^0.1.1-rc.6",
110
+ "@hydraharness/harness-subagent-spawn-in-process": "^0.1.1-rc.6",
111
+ "@hydraharness/harness-system-prompt": "^0.1.1-rc.6",
112
+ "@hydraharness/harness-subprocess-local": "^0.1.1-rc.6",
113
+ "@hydraharness/harness-token-meter": "^0.1.1-rc.6",
114
+ "@hydraharness/harness-tool-bash": "^0.1.1-rc.6",
115
+ "@hydraharness/harness-tool-call-timeout-policy": "^0.1.1-rc.6",
116
+ "@hydraharness/harness-tool-fs": "^0.1.1-rc.6",
117
+ "@hydraharness/harness-tool-fs-search": "^0.1.1-rc.6",
118
+ "@hydraharness/harness-tool-goal": "^0.1.1-rc.6",
119
+ "@hydraharness/harness-tool-pwsh": "^0.1.1-rc.6",
120
+ "@hydraharness/harness-tool-jobs": "^0.1.1-rc.6",
121
+ "@hydraharness/harness-tool-lsp": "^0.1.1-rc.6",
122
+ "@hydraharness/harness-tool-ralph": "^0.1.1-rc.6",
123
+ "@hydraharness/harness-tool-session-version": "^0.1.1-rc.6",
124
+ "@hydraharness/harness-tool-skill": "^0.1.1-rc.6",
125
+ "@hydraharness/harness-tool-media": "^0.1.1-rc.6",
126
+ "@hydraharness/harness-tool-str-replace-editor": "^0.1.1-rc.6",
127
+ "@hydraharness/harness-tool-subagent": "^0.1.1-rc.6",
128
+ "@hydraharness/harness-tool-subagent-control": "^0.1.1-rc.6",
129
+ "@hydraharness/harness-tool-todo": "^0.1.1-rc.6",
130
+ "@hydraharness/harness-tool-subagent-report": "^0.1.1-rc.6",
131
+ "@hydraharness/harness-tools": "^0.1.1-rc.6",
132
+ "@hydraharness/harness-typert-loader": "^0.1.1-rc.6",
133
+ "@hydraharness/harness-typert-registry": "^0.1.1-rc.6",
134
+ "@hydraharness/harness-tool-web": "^0.1.1-rc.6",
135
+ "@hydraharness/harness-tool-workflow": "^0.1.1-rc.6",
136
+ "@hydraharness/harness-user-approval": "^0.1.1-rc.6",
137
+ "@hydraharness/harness-web": "^0.1.1-rc.6",
138
+ "@hydraharness/harness-web-fetch-http": "^0.1.1-rc.6",
139
+ "@hydraharness/harness-workflow-worker-thread": "^0.1.1-rc.6",
140
+ "@hydraharness/harness-user-questions": "^0.1.1-rc.6",
141
+ "@hydraharness/harness-web-search-deepseek": "^0.1.1-rc.6",
142
+ "@hydraharness/harness-web-search-http": "^0.1.1-rc.6"
143
+ },
144
+ "peerDependencies": {
145
+ "@hydraharness/cordis": "^4.0.2",
146
+ "@hydraharness/harness-invariants": "^0.1.1-rc.6"
147
+ },
148
+ "devDependencies": {
149
+ "@hydraharness/cordis": "^4.0.2",
150
+ "@hydraharness/harness-invariants": "^0.1.1-rc.6"
151
+ }
152
+ }