@syncended/dsh-automations 0.5.0 → 0.6.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/README.md +6 -6
- package/dist/agent-executor.js +2 -2
- package/dist/agent-executor.js.map +1 -1
- package/dist/project-policy.js +4 -4
- package/dist/project-policy.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/architecture.md +4 -4
- package/docs/security.md +2 -2
- package/lib/client.js +188 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# DeepSeek Harness Automations
|
|
2
2
|
|
|
3
|
-
A DeepSeek Harness plugin for durable, configurable cron jobs. Each occurrence starts a fresh persisted Harness Agent in a selected
|
|
3
|
+
A DeepSeek Harness plugin for durable, configurable cron jobs. Each occurrence starts a fresh persisted Harness Agent in a selected workspace with an explicit model route, agent preset, and permission preset.
|
|
4
4
|
|
|
5
5
|
> **Status:** MVP for `@deepseek-ai/dsh` `0.1.1-rc.2`. The current worker is single-host. Cron admission and run history are durable; an already-started run is deliberately **not** retried after a host crash.
|
|
6
6
|
|
|
7
7
|
## What works
|
|
8
8
|
|
|
9
9
|
- Standard five-field cron expressions with `UTC` or IANA timezones.
|
|
10
|
-
- Per-job
|
|
10
|
+
- Per-job workspace, provider/model, reasoning effort, agent preset, permission preset, and timeout.
|
|
11
11
|
- Enable/disable, Run now, edit, delete, cancel, and recent run history from a full center workspace opened by the main **Automations** sidebar action, or from **Settings → Automations**.
|
|
12
12
|
- Overlap policies:
|
|
13
13
|
- `skip` — record and skip an occurrence while the job has queued/running work.
|
|
@@ -20,7 +20,7 @@ A DeepSeek Harness plugin for durable, configurable cron jobs. Each occurrence s
|
|
|
20
20
|
- Immutable execution snapshots and occurrence keys for replay-safe admission.
|
|
21
21
|
- Extensible executor registry: the MVP ships `agent`; future `workflow` and task-graph executors do not need scheduler changes.
|
|
22
22
|
|
|
23
|
-
The in-box `@deepseek-ai/dsh-schedule` plugin remains the right tool for reminders attached to one live Session. This plugin owns deployment-level jobs that can start a fresh
|
|
23
|
+
The in-box `@deepseek-ai/dsh-schedule` plugin remains the right tool for reminders attached to one live Session. This plugin owns deployment-level jobs that can start a fresh workspace Session while no chat is open.
|
|
24
24
|
|
|
25
25
|
## Install
|
|
26
26
|
|
|
@@ -57,10 +57,10 @@ dsh plugin --profile web remove @syncended/dsh-automations
|
|
|
57
57
|
| Name | Human-readable job name. |
|
|
58
58
|
| Cron | Five fields: `minute hour day-of-month month day-of-week`. Example: `0 9 * * 1-5`. |
|
|
59
59
|
| Time zone | Search by city or region in the picker, or enter `UTC` / an IANA name such as `Europe/Berlin`. Current UTC offsets are shown; DST is handled by `cron-parser`. |
|
|
60
|
-
|
|
|
60
|
+
| Workspace | Choose an existing Harness workspace or enter an absolute directory manually. Its canonical filesystem identity becomes the Session cwd and `workspace-write` root. |
|
|
61
61
|
| Prompt | The user message sent to a fresh Harness Agent. |
|
|
62
62
|
| Provider / model | Choose a configured provider in the searchable picker or enter an unlisted adapter route, then choose or enter its model. Leave both blank to resolve the current Harness default at dispatch time. |
|
|
63
|
-
| Reasoning effort | Choose `Default` or an exact-model effort advertised by the adapter.
|
|
63
|
+
| Reasoning effort | Choose `Default` or an exact-model effort advertised by the adapter. If capability lookup is unavailable, common IDs are shown as advisory fallbacks; custom IDs remain editable and are validated when the run starts. |
|
|
64
64
|
| Agent preset | Leave blank for the current Harness default, or select a specific composition. |
|
|
65
65
|
| Permission preset | Bundles DSH sandbox and approval policies. Default: `workspace-write`. |
|
|
66
66
|
| Timeout | Wall-clock run limit. Cancellation is cooperative through the Agent loop. |
|
|
@@ -101,7 +101,7 @@ This is not exactly-once execution. Exactly-once external side effects require i
|
|
|
101
101
|
## Security
|
|
102
102
|
|
|
103
103
|
- State files are replaced atomically with mode `0600`; created directories use `0700`.
|
|
104
|
-
-
|
|
104
|
+
- Workspace paths are resolved through `realpath`; optional allowed roots are checked against that canonical identity.
|
|
105
105
|
- Background work uses a normal DSH permission preset. `workspace-write` cannot silently widen itself; unattended approval failures remain fail-closed.
|
|
106
106
|
- `danger-full-access` is intentionally available only when the job author selects a configured preset that grants it.
|
|
107
107
|
- The management API requires JSON plus a custom same-origin mutation header. It inherits the trust boundary of the DSH Web server, which has no standalone authentication layer.
|
package/dist/agent-executor.js
CHANGED
|
@@ -58,9 +58,9 @@ function failureFromReason(reason) {
|
|
|
58
58
|
async function assertCanonicalDirectory(cwd) {
|
|
59
59
|
const [metadata, canonical] = await Promise.all([stat(cwd), realpath(cwd)]);
|
|
60
60
|
if (!metadata.isDirectory())
|
|
61
|
-
throw new AgentRunError(`
|
|
61
|
+
throw new AgentRunError(`Workspace path is not a directory: ${cwd}`, 'PROJECT_NOT_DIRECTORY');
|
|
62
62
|
if (canonical !== cwd) {
|
|
63
|
-
throw new AgentRunError(`
|
|
63
|
+
throw new AgentRunError(`Workspace path no longer resolves to its saved filesystem identity: expected ${cwd}, found ${canonical}`, 'PROJECT_IDENTITY_CHANGED');
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
function resolveSelection(ctx, run) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-executor.js","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"agent-executor.js","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"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"}
|
package/dist/project-policy.js
CHANGED
|
@@ -33,16 +33,16 @@ export class ProjectPolicy {
|
|
|
33
33
|
const roots = [];
|
|
34
34
|
for (const configured of configuredRoots) {
|
|
35
35
|
const path = resolve(expandHomePath(configured));
|
|
36
|
-
roots.push(await canonicalDirectory(path, 'allowed
|
|
36
|
+
roots.push(await canonicalDirectory(path, 'allowed workspace root'));
|
|
37
37
|
}
|
|
38
38
|
return new ProjectPolicy([...new Set(roots)]);
|
|
39
39
|
}
|
|
40
40
|
async authorize(cwd) {
|
|
41
41
|
if (!isAbsolute(cwd))
|
|
42
|
-
throw new AutomationInputError('
|
|
43
|
-
const canonical = await canonicalDirectory(cwd, '
|
|
42
|
+
throw new AutomationInputError('workspace path must be absolute');
|
|
43
|
+
const canonical = await canonicalDirectory(cwd, 'workspace path');
|
|
44
44
|
if (this.roots.length > 0 && !this.roots.some((root) => isWithin(root, canonical))) {
|
|
45
|
-
throw new AutomationInputError(`
|
|
45
|
+
throw new AutomationInputError(`workspace path is outside allowedProjectRoots: ${canonical}`, 'PROJECT_NOT_ALLOWED', 403);
|
|
46
46
|
}
|
|
47
47
|
return canonical;
|
|
48
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-policy.js","sourceRoot":"","sources":["../src/project-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AACrE,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAa;IAC3D,IAAI,QAAQ,CAAA;IACZ,IAAI,SAAS,CAAA;IACb,IAAI,CAAC;QACH,CAAC;QAAA,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,oBAAoB,CAAC,GAAG,KAAK,oCAAoC,IAAI,EAAE,EAAE,qBAAqB,EAAE,GAAG,EAAE;YAC7G,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,oBAAoB,CAAC,GAAG,KAAK,wBAAwB,IAAI,EAAE,EAAE,uBAAuB,CAAC,CAAA;IACjG,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,oFAAoF;AACpF,MAAM,OAAO,aAAa;IACP,KAAK,CAAU;IAEhC,YAAoB,KAAe;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAkC;QACpD,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,KAAK,MAAM,UAAU,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;YAChD,KAAK,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"project-policy.js","sourceRoot":"","sources":["../src/project-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AACrE,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAa;IAC3D,IAAI,QAAQ,CAAA;IACZ,IAAI,SAAS,CAAA;IACb,IAAI,CAAC;QACH,CAAC;QAAA,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,oBAAoB,CAAC,GAAG,KAAK,oCAAoC,IAAI,EAAE,EAAE,qBAAqB,EAAE,GAAG,EAAE;YAC7G,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,oBAAoB,CAAC,GAAG,KAAK,wBAAwB,IAAI,EAAE,EAAE,uBAAuB,CAAC,CAAA;IACjG,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,oFAAoF;AACpF,MAAM,OAAO,aAAa;IACP,KAAK,CAAU;IAEhC,YAAoB,KAAe;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAkC;QACpD,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,KAAK,MAAM,UAAU,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;YAChD,KAAK,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAA;QACtE,CAAC;QACD,OAAO,IAAI,aAAa,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,iCAAiC,CAAC,CAAA;QACvF,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;QACjE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YACnF,MAAM,IAAI,oBAAoB,CAC5B,kDAAkD,SAAS,EAAE,EAC7D,qBAAqB,EACrB,GAAG,CACJ,CAAA;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface CronSchedule {
|
|
|
12
12
|
timezone: string;
|
|
13
13
|
}
|
|
14
14
|
export interface AgentExecutionSpec {
|
|
15
|
-
/** Absolute
|
|
15
|
+
/** Absolute workspace directory and immutable Session cwd/root. */
|
|
16
16
|
cwd: string;
|
|
17
17
|
/** Omitted provider and model resolve from the current Harness default at dispatch time. */
|
|
18
18
|
provider?: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,eAAO,MAAM,oBAAoB,EAAG,CAAU,CAAA;AAC9C,eAAO,MAAM,oBAAoB,EAAG,4BAAqC,CAAA;AAEzE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AACtD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAA;AAC/C,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,CAAA;AACjD,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,GACR,SAAS,GACT,WAAW,GACX,QAAQ,GACR,WAAW,GACX,WAAW,GACX,SAAS,GACT,aAAa,CAAA;AAEjB,MAAM,WAAW,YAAY;IAC3B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/docs/architecture.md
CHANGED
|
@@ -32,11 +32,11 @@ Sidebar / Center workspace / Settings UI / HTTP API
|
|
|
32
32
|
|
|
33
33
|
The same automation page is available through Settings and a dedicated center workspace. `settings.section` keeps configuration available inside Settings; `sidebar.footer.action` activates a temporary, higher-priority `conversation` entry that replaces the current center occupant. This provides a split-screen-like full-center experience while using the single-slot election directly rather than Split Screen's internal view contributions. Closing Automations disposes its entry immediately, revealing whichever center surface was previously active. A small client-only disclosure store coordinates the sidebar trigger and dynamic registration; neither surface owns scheduler state, and both read the same package HTTP API.
|
|
34
34
|
|
|
35
|
-
Interactive chrome uses the ambient `@deepseek-ai/dsh-client-ui-primitives` `Button`, `Menu`, and icon components. Package CSS is limited to the automation-specific layout and composes only public DSH semantic tokens, so theme, menu, focus, and button behavior stay aligned with the host UI.
|
|
35
|
+
Interactive chrome uses the ambient `@deepseek-ai/dsh-client-ui-primitives` `Button`, `Menu`, and icon components. The Workspace selector subscribes to `ctx.workspaces.list`, projecting the Host's live workspace order while retaining manual absolute-path entry. Package CSS is limited to the automation-specific layout and composes only public DSH semantic tokens, so theme, menu, focus, and button behavior stay aligned with the host UI.
|
|
36
36
|
|
|
37
37
|
### AutomationService
|
|
38
38
|
|
|
39
|
-
Cordis service `ctx.automations`. It owns input validation, canonical
|
|
39
|
+
Cordis service `ctx.automations`. It owns input validation, canonical workspace-path authorization, metadata discovery, the Web route, and the public executor-registration seam.
|
|
40
40
|
|
|
41
41
|
### AutomationStateStore
|
|
42
42
|
|
|
@@ -72,7 +72,7 @@ It never knows how an Agent, workflow, or code task works.
|
|
|
72
72
|
|
|
73
73
|
The `agent` executor:
|
|
74
74
|
|
|
75
|
-
1. re-authorizes the canonical
|
|
75
|
+
1. re-authorizes the canonical workspace path;
|
|
76
76
|
2. resolves the job's agent and permission presets;
|
|
77
77
|
3. resolves the current default model or the pinned provider/model route;
|
|
78
78
|
4. creates a fresh Session and Agent through `ctx.agents.create`;
|
|
@@ -123,7 +123,7 @@ A queued run must not change when a user edits or deletes its source job. The sn
|
|
|
123
123
|
- job id/version and name;
|
|
124
124
|
- schedule/policy values used at admission;
|
|
125
125
|
- prompt and execution settings;
|
|
126
|
-
-
|
|
126
|
+
- workspace/model/preset/permission/timeout values.
|
|
127
127
|
|
|
128
128
|
Deleting a job marks its still-queued runs skipped; already-running work drains against its snapshot.
|
|
129
129
|
|
package/docs/security.md
CHANGED
|
@@ -16,7 +16,7 @@ The custom header forces a cross-origin browser request through CORS preflight,
|
|
|
16
16
|
|
|
17
17
|
## Filesystem authority
|
|
18
18
|
|
|
19
|
-
A job's
|
|
19
|
+
A job's workspace path is canonicalized with `realpath` before storage. `workspace-write` uses that Session cwd as its DSH sandbox root. `allowedProjectRoots`, when configured, are canonicalized and checked with path-segment containment rather than string prefixes.
|
|
20
20
|
|
|
21
21
|
The executor repeats authorization at dispatch, catching deleted paths and symlink retargeting after configuration.
|
|
22
22
|
|
|
@@ -32,7 +32,7 @@ Scheduled Agents are not attached to an interactive browser ownership chain. A p
|
|
|
32
32
|
|
|
33
33
|
## Secrets and persisted data
|
|
34
34
|
|
|
35
|
-
`state.json` contains job prompts,
|
|
35
|
+
`state.json` contains job prompts, workspace paths, model/preset selections, run metadata, and bounded final assistant text. It is atomically replaced with mode `0600`; parent directories created by the plugin use `0700`. Session transcripts are persisted by the configured Harness Session backend and may contain substantially more data.
|
|
36
36
|
|
|
37
37
|
Do not put API keys directly in prompts. Use normal Harness credential providers and environment policy.
|
|
38
38
|
|
package/lib/client.js
CHANGED
|
@@ -24,6 +24,7 @@ window.__ModuleLoader__.load({
|
|
|
24
24
|
IconChevronDownOutline14,
|
|
25
25
|
IconChevronLeftOutline14,
|
|
26
26
|
IconEditOutline16,
|
|
27
|
+
IconFolderClose16,
|
|
27
28
|
IconGlobeOutline14,
|
|
28
29
|
IconPlayOutline16,
|
|
29
30
|
IconPlusOutline16,
|
|
@@ -33,7 +34,7 @@ window.__ModuleLoader__.load({
|
|
|
33
34
|
IconTrashOutline16,
|
|
34
35
|
IconWarningOutline16,
|
|
35
36
|
} = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
36
|
-
const inject = ["slots"];
|
|
37
|
+
const inject = ["slots", "workspaces"];
|
|
37
38
|
|
|
38
39
|
const API_PREFIX = "/api/automations";
|
|
39
40
|
const POLL_MS = 5000;
|
|
@@ -124,6 +125,20 @@ window.__ModuleLoader__.load({
|
|
|
124
125
|
});
|
|
125
126
|
|
|
126
127
|
const MODEL_METADATA_CACHE = new Map();
|
|
128
|
+
const COMMON_EFFORT_FALLBACKS = [
|
|
129
|
+
{ id: "off", name: "Off", description: "Disable extended reasoning when the adapter supports it." },
|
|
130
|
+
{ id: "minimal", name: "Minimal", description: "Use the lightest available reasoning level." },
|
|
131
|
+
{ id: "low", name: "Low", description: "Use a lower-cost reasoning level." },
|
|
132
|
+
{ id: "medium", name: "Medium", description: "Use a balanced reasoning level." },
|
|
133
|
+
{ id: "high", name: "High", description: "Use a deeper reasoning level." },
|
|
134
|
+
{ id: "max", name: "Max", description: "Use the strongest available reasoning level." },
|
|
135
|
+
];
|
|
136
|
+
const EMPTY_WORKSPACE_SNAPSHOT = Object.freeze({
|
|
137
|
+
items: Object.freeze([]),
|
|
138
|
+
state: "idle",
|
|
139
|
+
phase: "pending",
|
|
140
|
+
error: null,
|
|
141
|
+
});
|
|
127
142
|
const OVERLAP_OPTIONS = [
|
|
128
143
|
{ value: "skip", label: "skip", hint: "Skip the run if a previous run is still active." },
|
|
129
144
|
{ value: "queue", label: "queue", hint: "Defer the run until the previous run finishes." },
|
|
@@ -691,6 +706,7 @@ window.__ModuleLoader__.load({
|
|
|
691
706
|
const {
|
|
692
707
|
id,
|
|
693
708
|
value,
|
|
709
|
+
displayValue,
|
|
694
710
|
onChange,
|
|
695
711
|
optionsForQuery,
|
|
696
712
|
selectedId,
|
|
@@ -931,7 +947,7 @@ window.__ModuleLoader__.load({
|
|
|
931
947
|
className: "dsh-auto-combobox-input",
|
|
932
948
|
type: "text",
|
|
933
949
|
role: "combobox",
|
|
934
|
-
value,
|
|
950
|
+
value: !searching && displayValue !== undefined ? displayValue : value,
|
|
935
951
|
placeholder,
|
|
936
952
|
disabled,
|
|
937
953
|
autoComplete: "off",
|
|
@@ -1018,12 +1034,117 @@ window.__ModuleLoader__.load({
|
|
|
1018
1034
|
});
|
|
1019
1035
|
}
|
|
1020
1036
|
|
|
1037
|
+
function looksLikeAbsolutePath(value) {
|
|
1038
|
+
const path = String(value || "").trim();
|
|
1039
|
+
return path.charAt(0) === "/" || /^[A-Za-z]:[\\/]/.test(path) || path.startsWith("\\\\");
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
function workspacePathName(path) {
|
|
1043
|
+
const withoutTrailingSeparators = String(path || "").replace(/[\\/]+$/, "");
|
|
1044
|
+
const segments = withoutTrailingSeparators.split(/[\\/]/).filter(Boolean);
|
|
1045
|
+
return segments[segments.length - 1] || String(path || "");
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
function normalizedWorkspaces(workspaces) {
|
|
1049
|
+
const seenPaths = new Set();
|
|
1050
|
+
return (Array.isArray(workspaces) ? workspaces : [])
|
|
1051
|
+
.map((workspace, index) => {
|
|
1052
|
+
if (!workspace || typeof workspace.path !== "string" || workspace.path.trim() === "") return null;
|
|
1053
|
+
const path = workspace.path.trim();
|
|
1054
|
+
if (seenPaths.has(path)) return null;
|
|
1055
|
+
seenPaths.add(path);
|
|
1056
|
+
const rawTitle = typeof workspace.title === "string" ? workspace.title.trim() : "";
|
|
1057
|
+
return {
|
|
1058
|
+
id: String(workspace.workspaceId || workspace.id || "workspace-" + index),
|
|
1059
|
+
path,
|
|
1060
|
+
title: rawTitle || workspacePathName(path),
|
|
1061
|
+
sessionCount: Array.isArray(workspace.sessionIds) ? workspace.sessionIds.length : 0,
|
|
1062
|
+
};
|
|
1063
|
+
})
|
|
1064
|
+
.filter(Boolean);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function preferredWorkspacePath(workspaceSnapshot) {
|
|
1068
|
+
const catalog = normalizedWorkspaces(workspaceSnapshot?.items);
|
|
1069
|
+
const recentId = workspaceSnapshot?.recentWorkspaceId;
|
|
1070
|
+
const recent = recentId === undefined
|
|
1071
|
+
? null
|
|
1072
|
+
: catalog.find((workspace) => workspace.id === String(recentId));
|
|
1073
|
+
return (recent || catalog[0] || {}).path || "";
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
function WorkspacePicker({ id, value, workspaceSnapshot, onChange }) {
|
|
1077
|
+
const catalog = normalizedWorkspaces(workspaceSnapshot?.items);
|
|
1078
|
+
const exactValue = value.trim();
|
|
1079
|
+
const selected = catalog.find((workspace) => workspace.path === exactValue) || null;
|
|
1080
|
+
const custom = exactValue !== "" && selected === null && looksLikeAbsolutePath(exactValue);
|
|
1081
|
+
const options = [
|
|
1082
|
+
...catalog.map((workspace) => ({
|
|
1083
|
+
id: "workspace:" + workspace.id,
|
|
1084
|
+
value: workspace.path,
|
|
1085
|
+
label: workspace.title,
|
|
1086
|
+
detail: workspace.path + " · " + workspace.sessionCount + (workspace.sessionCount === 1 ? " session" : " sessions"),
|
|
1087
|
+
aliases: [workspace.id, workspacePathName(workspace.path)],
|
|
1088
|
+
Icon: IconFolderClose16,
|
|
1089
|
+
})),
|
|
1090
|
+
...(custom
|
|
1091
|
+
? [{
|
|
1092
|
+
id: "custom-workspace:" + exactValue,
|
|
1093
|
+
value: exactValue,
|
|
1094
|
+
label: workspacePathName(exactValue) || exactValue,
|
|
1095
|
+
detail: exactValue + " · Custom absolute path",
|
|
1096
|
+
aliases: [exactValue],
|
|
1097
|
+
custom: true,
|
|
1098
|
+
Icon: IconFolderClose16,
|
|
1099
|
+
}]
|
|
1100
|
+
: []),
|
|
1101
|
+
];
|
|
1102
|
+
let panelNotice = null;
|
|
1103
|
+
if (workspaceSnapshot?.state === "error") {
|
|
1104
|
+
panelNotice = "Harness workspaces are unavailable. You can still enter an absolute directory path.";
|
|
1105
|
+
} else if (workspaceSnapshot?.phase !== "ready" && catalog.length === 0) {
|
|
1106
|
+
panelNotice = "Loading Harness workspaces. You can still enter an absolute directory path.";
|
|
1107
|
+
}
|
|
1108
|
+
return h(EditableCombobox, {
|
|
1109
|
+
id,
|
|
1110
|
+
value,
|
|
1111
|
+
displayValue: selected ? selected.title : undefined,
|
|
1112
|
+
onChange,
|
|
1113
|
+
optionsForQuery: (query) => comboboxSearchResults(options, query),
|
|
1114
|
+
selectedId: selected ? "workspace:" + selected.id : custom ? "custom-workspace:" + exactValue : null,
|
|
1115
|
+
commitExactValue: (raw) => {
|
|
1116
|
+
const path = raw.trim();
|
|
1117
|
+
return looksLikeAbsolutePath(path) ? path : null;
|
|
1118
|
+
},
|
|
1119
|
+
placeholder: "Choose a Harness workspace or enter a path",
|
|
1120
|
+
Icon: IconFolderClose16,
|
|
1121
|
+
listboxLabel: "Harness workspaces",
|
|
1122
|
+
initialTitle: "Harness workspaces",
|
|
1123
|
+
searchTitle: "Matching workspaces",
|
|
1124
|
+
emptyText: catalog.length === 0
|
|
1125
|
+
? "No Harness workspaces are registered. Enter an absolute directory path."
|
|
1126
|
+
: "No matching workspaces. Enter an absolute directory path to use it directly.",
|
|
1127
|
+
hintText: "Choose a registered workspace or enter an absolute path without registering it.",
|
|
1128
|
+
resultNoun: "workspace",
|
|
1129
|
+
invalidMessage: "Enter an absolute workspace path.",
|
|
1130
|
+
invalid: exactValue !== "" && !looksLikeAbsolutePath(exactValue),
|
|
1131
|
+
resumeSearch: custom,
|
|
1132
|
+
panelNotice,
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
function providerFallbackName(id) {
|
|
1137
|
+
return humanizePresetId(id)
|
|
1138
|
+
.replace(/^Openai\b/, "OpenAI")
|
|
1139
|
+
.replace(/^Deepseek\b/, "DeepSeek");
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1021
1142
|
function normalizedProviders(providers) {
|
|
1022
1143
|
return (Array.isArray(providers) ? providers : [])
|
|
1023
1144
|
.filter((provider) => provider && typeof provider.id === "string" && provider.id !== "")
|
|
1024
1145
|
.map((provider) => ({
|
|
1025
1146
|
id: provider.id,
|
|
1026
|
-
name: typeof provider.name === "string" && provider.name !== "" ? provider.name : provider.id,
|
|
1147
|
+
name: typeof provider.name === "string" && provider.name !== "" ? provider.name : providerFallbackName(provider.id),
|
|
1027
1148
|
models: (Array.isArray(provider.models) ? provider.models : [])
|
|
1028
1149
|
.map((model) => typeof model === "string"
|
|
1029
1150
|
? { id: model, name: model }
|
|
@@ -1137,6 +1258,15 @@ window.__ModuleLoader__.load({
|
|
|
1137
1258
|
: { key: cacheKey, status: cacheKey ? "loading" : "idle", data: null, error: null };
|
|
1138
1259
|
}
|
|
1139
1260
|
|
|
1261
|
+
function reasoningEffortsForState(modelState) {
|
|
1262
|
+
const advertised = modelState.status === "ready" && modelState.data?.reasoning
|
|
1263
|
+
&& Array.isArray(modelState.data.reasoning.efforts)
|
|
1264
|
+
? modelState.data.reasoning.efforts
|
|
1265
|
+
: null;
|
|
1266
|
+
if (advertised) return advertised;
|
|
1267
|
+
return modelState.status === "error" ? COMMON_EFFORT_FALLBACKS : [];
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1140
1270
|
function ReasoningEffortPicker({ id, value, provider, model, defaultModel, onChange }) {
|
|
1141
1271
|
const inherited = provider.trim() === "" && model.trim() === "";
|
|
1142
1272
|
const exactProvider = inherited ? String(defaultModel?.provider || "") : provider.trim();
|
|
@@ -1145,7 +1275,7 @@ window.__ModuleLoader__.load({
|
|
|
1145
1275
|
const reasoning = modelState.status === "ready" && modelState.data
|
|
1146
1276
|
? modelState.data.reasoning
|
|
1147
1277
|
: undefined;
|
|
1148
|
-
const efforts =
|
|
1278
|
+
const efforts = reasoningEffortsForState(modelState);
|
|
1149
1279
|
const known = value === "" || efforts.some((effort) => effort.id === value);
|
|
1150
1280
|
const advertisedDefault = inherited
|
|
1151
1281
|
? defaultModel?.reasoningEffort
|
|
@@ -1189,7 +1319,7 @@ window.__ModuleLoader__.load({
|
|
|
1189
1319
|
} else if (modelState.status === "loading") {
|
|
1190
1320
|
panelNotice = "Loading effort levels for " + exactProvider + " / " + exactModel + "…";
|
|
1191
1321
|
} else if (modelState.status === "error") {
|
|
1192
|
-
panelNotice = "
|
|
1322
|
+
panelNotice = "Exact-model metadata is unavailable. Common effort IDs are advisory; custom IDs remain available.";
|
|
1193
1323
|
} else if (modelState.status === "ready" && !reasoning) {
|
|
1194
1324
|
panelNotice = "This model does not advertise selectable effort levels. Custom IDs remain available.";
|
|
1195
1325
|
}
|
|
@@ -1376,7 +1506,7 @@ window.__ModuleLoader__.load({
|
|
|
1376
1506
|
}
|
|
1377
1507
|
|
|
1378
1508
|
function JobForm(props) {
|
|
1379
|
-
const { meta, draft, editing, saving, error, onChange, onIdTouched, onSubmit, onCancel } = props;
|
|
1509
|
+
const { meta, workspaceSnapshot, draft, editing, saving, error, onChange, onIdTouched, onSubmit, onCancel } = props;
|
|
1380
1510
|
const providers = normalizedProviders(meta && Array.isArray(meta.providers) ? meta.providers : []);
|
|
1381
1511
|
const providerModels = providers.find((provider) => provider.id === draft.provider);
|
|
1382
1512
|
const models = providerModels ? providerModels.models : [];
|
|
@@ -1611,15 +1741,18 @@ window.__ModuleLoader__.load({
|
|
|
1611
1741
|
),
|
|
1612
1742
|
h(
|
|
1613
1743
|
Field,
|
|
1614
|
-
{
|
|
1615
|
-
|
|
1744
|
+
{
|
|
1745
|
+
label: "Workspace",
|
|
1746
|
+
htmlFor: fieldId("cwd"),
|
|
1747
|
+
required: true,
|
|
1748
|
+
full: true,
|
|
1749
|
+
hint: "Choose a Harness workspace or enter the absolute directory where the agent runs.",
|
|
1750
|
+
},
|
|
1751
|
+
h(WorkspacePicker, {
|
|
1616
1752
|
id: fieldId("cwd"),
|
|
1617
|
-
className: "dsh-auto-input",
|
|
1618
|
-
type: "text",
|
|
1619
1753
|
value: draft.cwd,
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
onChange: (event) => onChange("cwd", event.target.value),
|
|
1754
|
+
workspaceSnapshot,
|
|
1755
|
+
onChange: (value) => onChange("cwd", value),
|
|
1623
1756
|
}),
|
|
1624
1757
|
),
|
|
1625
1758
|
h(
|
|
@@ -1911,7 +2044,21 @@ window.__ModuleLoader__.load({
|
|
|
1911
2044
|
);
|
|
1912
2045
|
}
|
|
1913
2046
|
|
|
1914
|
-
function
|
|
2047
|
+
function useHarnessWorkspaceSnapshot(workspaceRuntime) {
|
|
2048
|
+
const list = workspaceRuntime?.list;
|
|
2049
|
+
const subscribe = useCallback(
|
|
2050
|
+
(listener) => list ? list.subscribe(listener) : () => {},
|
|
2051
|
+
[list],
|
|
2052
|
+
);
|
|
2053
|
+
const getSnapshot = useCallback(
|
|
2054
|
+
() => list ? list.getSnapshot() : EMPTY_WORKSPACE_SNAPSHOT,
|
|
2055
|
+
[list],
|
|
2056
|
+
);
|
|
2057
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
function AutomationsSection({ centerMode = false, workspaceRuntime = null } = {}) {
|
|
2061
|
+
const workspaceSnapshot = useHarnessWorkspaceSnapshot(workspaceRuntime);
|
|
1915
2062
|
const [meta, setMeta] = useState(null);
|
|
1916
2063
|
const [snapshot, setSnapshot] = useState(null);
|
|
1917
2064
|
const [loading, setLoading] = useState(true);
|
|
@@ -1930,6 +2077,7 @@ window.__ModuleLoader__.load({
|
|
|
1930
2077
|
const pollRef = useRef(false);
|
|
1931
2078
|
const hasDataRef = useRef(false);
|
|
1932
2079
|
const idTouchedRef = useRef(false);
|
|
2080
|
+
const workspaceTouchedRef = useRef(false);
|
|
1933
2081
|
const flashTimerRef = useRef(null);
|
|
1934
2082
|
|
|
1935
2083
|
const loadMeta = useCallback(async () => {
|
|
@@ -2075,14 +2223,16 @@ window.__ModuleLoader__.load({
|
|
|
2075
2223
|
const openCreate = useCallback(() => {
|
|
2076
2224
|
setEditing(null);
|
|
2077
2225
|
idTouchedRef.current = false;
|
|
2078
|
-
|
|
2226
|
+
workspaceTouchedRef.current = false;
|
|
2227
|
+
setDraft(Object.assign(emptyDraft(meta), { cwd: preferredWorkspacePath(workspaceSnapshot) }));
|
|
2079
2228
|
setFormError(null);
|
|
2080
2229
|
setFormOpen(true);
|
|
2081
|
-
}, [meta]);
|
|
2230
|
+
}, [meta, workspaceSnapshot]);
|
|
2082
2231
|
|
|
2083
2232
|
const openEdit = useCallback((job) => {
|
|
2084
2233
|
setEditing(job);
|
|
2085
2234
|
idTouchedRef.current = true;
|
|
2235
|
+
workspaceTouchedRef.current = true;
|
|
2086
2236
|
setDraft(draftFromJob(job));
|
|
2087
2237
|
setFormError(null);
|
|
2088
2238
|
setFormOpen(true);
|
|
@@ -2094,8 +2244,16 @@ window.__ModuleLoader__.load({
|
|
|
2094
2244
|
setFormError(null);
|
|
2095
2245
|
}, []);
|
|
2096
2246
|
|
|
2247
|
+
useEffect(() => {
|
|
2248
|
+
if (!formOpen || editing !== null || workspaceTouchedRef.current || draft.cwd !== "") return;
|
|
2249
|
+
const preferred = preferredWorkspacePath(workspaceSnapshot);
|
|
2250
|
+
if (preferred === "") return;
|
|
2251
|
+
setDraft((previous) => previous.cwd === "" ? Object.assign({}, previous, { cwd: preferred }) : previous);
|
|
2252
|
+
}, [formOpen, editing, draft.cwd, workspaceSnapshot]);
|
|
2253
|
+
|
|
2097
2254
|
const handleDraftChange = useCallback(
|
|
2098
2255
|
(key, value) => {
|
|
2256
|
+
if (key === "cwd") workspaceTouchedRef.current = true;
|
|
2099
2257
|
setDraft((previous) => {
|
|
2100
2258
|
let next = Object.assign({}, previous, { [key]: value });
|
|
2101
2259
|
if (key === "name" && editing === null && !idTouchedRef.current) {
|
|
@@ -2128,10 +2286,9 @@ window.__ModuleLoader__.load({
|
|
|
2128
2286
|
const timezone = draft.timezone.trim();
|
|
2129
2287
|
if (timezone === "") return setFormError("A timezone is required.");
|
|
2130
2288
|
const cwd = draft.cwd.trim();
|
|
2131
|
-
if (cwd === "") return setFormError("
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
return setFormError("The working directory must be an absolute filesystem path.");
|
|
2289
|
+
if (cwd === "") return setFormError("A workspace is required.");
|
|
2290
|
+
if (!looksLikeAbsolutePath(cwd)) {
|
|
2291
|
+
return setFormError("The workspace must be an absolute filesystem path.");
|
|
2135
2292
|
}
|
|
2136
2293
|
const prompt = draft.prompt.trim();
|
|
2137
2294
|
if (prompt === "") return setFormError("A prompt is required.");
|
|
@@ -2233,6 +2390,7 @@ window.__ModuleLoader__.load({
|
|
|
2233
2390
|
formOpen
|
|
2234
2391
|
? h(JobForm, {
|
|
2235
2392
|
meta,
|
|
2393
|
+
workspaceSnapshot,
|
|
2236
2394
|
draft,
|
|
2237
2395
|
editing,
|
|
2238
2396
|
saving: busy.save === true,
|
|
@@ -2402,7 +2560,7 @@ window.__ModuleLoader__.load({
|
|
|
2402
2560
|
);
|
|
2403
2561
|
}
|
|
2404
2562
|
|
|
2405
|
-
function AutomationsWorkspace({ disclosure }) {
|
|
2563
|
+
function AutomationsWorkspace({ disclosure, workspaceRuntime }) {
|
|
2406
2564
|
const workspaceRef = useRef(null);
|
|
2407
2565
|
const titleId = useId();
|
|
2408
2566
|
|
|
@@ -2450,7 +2608,7 @@ window.__ModuleLoader__.load({
|
|
|
2450
2608
|
"Exit Automations",
|
|
2451
2609
|
),
|
|
2452
2610
|
),
|
|
2453
|
-
h("div", { className: "dsh-auto-workspace-scroll" }, h(AutomationsSection, { centerMode: true })),
|
|
2611
|
+
h("div", { className: "dsh-auto-workspace-scroll" }, h(AutomationsSection, { centerMode: true, workspaceRuntime })),
|
|
2454
2612
|
);
|
|
2455
2613
|
}
|
|
2456
2614
|
|
|
@@ -2614,7 +2772,7 @@ window.__ModuleLoader__.load({
|
|
|
2614
2772
|
disposeCenter = ctx.slots.register({
|
|
2615
2773
|
name: "conversation",
|
|
2616
2774
|
priority: -200,
|
|
2617
|
-
inject: () => ({ disclosure }),
|
|
2775
|
+
inject: () => ({ disclosure, workspaceRuntime: ctx.workspaces }),
|
|
2618
2776
|
}, AutomationsWorkspace);
|
|
2619
2777
|
} catch (error) {
|
|
2620
2778
|
console.error("dsh automations: could not mount center workspace", error);
|
|
@@ -2658,6 +2816,7 @@ window.__ModuleLoader__.load({
|
|
|
2658
2816
|
id: "automations",
|
|
2659
2817
|
order: 25,
|
|
2660
2818
|
label: "Automations",
|
|
2819
|
+
inject: () => ({ workspaceRuntime: ctx.workspaces }),
|
|
2661
2820
|
}, AutomationsSection));
|
|
2662
2821
|
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
2663
2822
|
name: "sidebar.footer.action",
|
|
@@ -2672,6 +2831,7 @@ window.__ModuleLoader__.load({
|
|
|
2672
2831
|
exports.permissionPresetPresentation = permissionPresetPresentation;
|
|
2673
2832
|
exports.PermissionPresetPicker = PermissionPresetPicker;
|
|
2674
2833
|
exports.EditableCombobox = EditableCombobox;
|
|
2834
|
+
exports.WorkspacePicker = WorkspacePicker;
|
|
2675
2835
|
exports.ProviderPicker = ProviderPicker;
|
|
2676
2836
|
exports.ReasoningEffortPicker = ReasoningEffortPicker;
|
|
2677
2837
|
exports.TimeZonePicker = TimeZonePicker;
|
|
@@ -2679,7 +2839,12 @@ window.__ModuleLoader__.load({
|
|
|
2679
2839
|
nextFormInstancePrefix,
|
|
2680
2840
|
canonicalTimezone,
|
|
2681
2841
|
comboboxSearchResults,
|
|
2842
|
+
looksLikeAbsolutePath,
|
|
2843
|
+
normalizedWorkspaces,
|
|
2844
|
+
preferredWorkspacePath,
|
|
2682
2845
|
normalizedProviders,
|
|
2846
|
+
providerFallbackName,
|
|
2847
|
+
reasoningEffortsForState,
|
|
2683
2848
|
timezoneOffsetLabel,
|
|
2684
2849
|
timezoneNavigationIndex,
|
|
2685
2850
|
timezoneOptionPresentation,
|