@syncended/dsh-automations 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 +21 -0
- package/README.md +128 -0
- package/cordis.patch.yml +5 -0
- package/dist/agent-executor.d.ts +15 -0
- package/dist/agent-executor.d.ts.map +1 -0
- package/dist/agent-executor.js +173 -0
- package/dist/agent-executor.js.map +1 -0
- package/dist/cron.d.ts +15 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +74 -0
- package/dist/cron.js.map +1 -0
- package/dist/http.d.ts +8 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +203 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +201 -0
- package/dist/index.js.map +1 -0
- package/dist/project-policy.d.ts +9 -0
- package/dist/project-policy.d.ts.map +1 -0
- package/dist/project-policy.js +53 -0
- package/dist/project-policy.js.map +1 -0
- package/dist/scheduler.d.ts +58 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +518 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/state.d.ts +8 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +44 -0
- package/dist/state.js.map +1 -0
- package/dist/store.d.ts +21 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +317 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +13 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +159 -0
- package/dist/validation.js.map +1 -0
- package/docs/architecture.md +195 -0
- package/docs/http-api.md +40 -0
- package/docs/security.md +51 -0
- package/lib/client.js +1251 -0
- package/package.json +105 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 syncended
|
|
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,128 @@
|
|
|
1
|
+
# DeepSeek Harness Automations
|
|
2
|
+
|
|
3
|
+
A DeepSeek Harness plugin for durable, configurable cron jobs. Each occurrence starts a fresh persisted Harness Agent in a selected project with an explicit model route, agent preset, and permission preset.
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## What works
|
|
8
|
+
|
|
9
|
+
- Standard five-field cron expressions with `UTC` or IANA timezones.
|
|
10
|
+
- Per-job project directory, provider/model, reasoning effort, agent preset, permission preset, and timeout.
|
|
11
|
+
- Enable/disable, Run now, edit, delete, cancel, and recent run history in **Settings → Automations**.
|
|
12
|
+
- Overlap policies:
|
|
13
|
+
- `skip` — record and skip an occurrence while the job has queued/running work.
|
|
14
|
+
- `queue` — serialize occurrences for the same job.
|
|
15
|
+
- `allow` — permit concurrent occurrences, bounded by the global concurrency limit.
|
|
16
|
+
- Misfire policies:
|
|
17
|
+
- `skip` — record an overdue occurrence as skipped.
|
|
18
|
+
- `run-once` — coalesce missed occurrences to the latest due time.
|
|
19
|
+
- Atomic owner-private state under `$DSH_HOME/automations/state.json` by default.
|
|
20
|
+
- Immutable execution snapshots and occurrence keys for replay-safe admission.
|
|
21
|
+
- Extensible executor registry: the MVP ships `agent`; future `workflow` and task-graph executors do not need scheduler changes.
|
|
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 project Session while no chat is open.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
Requirements: Node.js 22+ and a working `dsh web` profile.
|
|
28
|
+
|
|
29
|
+
From npm:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dsh plugin --profile web add @syncended/dsh-automations
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or from this checkout:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm install
|
|
39
|
+
pnpm check
|
|
40
|
+
pnpm build
|
|
41
|
+
|
|
42
|
+
dsh plugin --profile web add .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The package declares a DSH bundle, so `dsh plugin` appends it to the Web profile automatically. Restart the running Web Harness after the initial install, then refresh the page. Open **Settings → Automations**.
|
|
46
|
+
|
|
47
|
+
To remove it:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
dsh plugin --profile web remove @syncended/dsh-automations
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configure a job
|
|
54
|
+
|
|
55
|
+
| Field | Meaning |
|
|
56
|
+
|---|---|
|
|
57
|
+
| Name | Human-readable job name. |
|
|
58
|
+
| Cron | Five fields: `minute hour day-of-month month day-of-week`. Example: `0 9 * * 1-5`. |
|
|
59
|
+
| Timezone | `UTC` or an IANA name such as `Europe/Berlin`. DST is handled by `cron-parser`. |
|
|
60
|
+
| Project | Existing absolute directory. Its canonical filesystem identity becomes the Session cwd and `workspace-write` root. |
|
|
61
|
+
| Prompt | The user message sent to a fresh Harness Agent. |
|
|
62
|
+
| Provider / model | Leave both blank to resolve the current Harness default at dispatch time. Set both to pin a route. |
|
|
63
|
+
| Reasoning effort | Optional adapter-owned value. |
|
|
64
|
+
| Agent preset | Leave blank for the current Harness default, or select a specific composition. |
|
|
65
|
+
| Permission preset | Bundles DSH sandbox and approval policies. Default: `workspace-write`. |
|
|
66
|
+
| Timeout | Wall-clock run limit. Cancellation is cooperative through the Agent loop. |
|
|
67
|
+
| Overlap / misfire | Admission behavior described above. |
|
|
68
|
+
|
|
69
|
+
A disabled job may still be started with **Run now**.
|
|
70
|
+
|
|
71
|
+
## Plugin configuration
|
|
72
|
+
|
|
73
|
+
Defaults are suitable for a local Web profile. Override the bundle row in the profile's `cordis.patch.yml` when needed:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
- id: automations
|
|
77
|
+
config:
|
|
78
|
+
maxConcurrentRuns: 2
|
|
79
|
+
historyLimit: 1000
|
|
80
|
+
misfireGraceMs: 60000
|
|
81
|
+
maxOutputChars: 65536
|
|
82
|
+
allowedProjectRoots:
|
|
83
|
+
- /home/me/projects
|
|
84
|
+
# Optional; otherwise $DSH_HOME/automations/state.json
|
|
85
|
+
# statePath: /absolute/private/path/state.json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`allowedProjectRoots: []` means the plugin accepts any existing directory the Harness host account can resolve. Configure one or more roots when the Web surface is exposed beyond a trusted local machine.
|
|
89
|
+
|
|
90
|
+
## Durable semantics
|
|
91
|
+
|
|
92
|
+
1. The scheduler claims an occurrence and advances its durable `nextRunAt` watermark in the **same atomic state mutation**.
|
|
93
|
+
2. The admitted run pins the complete job version and gets a unique occurrence key.
|
|
94
|
+
3. `queued` runs are dispatched after restart.
|
|
95
|
+
4. A run is marked `running` before any Agent work starts.
|
|
96
|
+
5. On restart, orphaned `running` records become `interrupted` and are not retried automatically, avoiding silent duplicate file/network effects.
|
|
97
|
+
6. Harness Session persistence remains the source of truth for the Agent transcript; the automation state stores orchestration metadata and a bounded final-text summary.
|
|
98
|
+
|
|
99
|
+
This is not exactly-once execution. Exactly-once external side effects require idempotency in the task itself or in the target system.
|
|
100
|
+
|
|
101
|
+
## Security
|
|
102
|
+
|
|
103
|
+
- State files are replaced atomically with mode `0600`; created directories use `0700`.
|
|
104
|
+
- Project paths are resolved through `realpath`; optional allowed roots are checked against that canonical identity.
|
|
105
|
+
- Background work uses a normal DSH permission preset. `workspace-write` cannot silently widen itself; unattended approval failures remain fail-closed.
|
|
106
|
+
- `danger-full-access` is intentionally available only when the job author selects a configured preset that grants it.
|
|
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.
|
|
108
|
+
- Prompts, run metadata, final summaries, and Session transcripts are local sensitive data.
|
|
109
|
+
|
|
110
|
+
See [`docs/security.md`](docs/security.md) for the threat model.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pnpm typecheck
|
|
116
|
+
pnpm test
|
|
117
|
+
pnpm check
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The Host plugin is TypeScript in `src/`. The browser half is deliberately plain JavaScript in `lib/client.js`, matching the external DSH Client Plugin loader format and avoiding a dependency on monorepo-only frontend build tooling.
|
|
121
|
+
|
|
122
|
+
## Architecture and roadmap
|
|
123
|
+
|
|
124
|
+
See [`docs/architecture.md`](docs/architecture.md). In short, cron is only a trigger. Durable runs call an executor selected by `task.kind`; the next implementation stage adds a `workflow` executor over `ctx.workflowEngine`, followed by a persisted task graph with leases, retries, child-agent references, and resumable code steps.
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { ProjectPolicy } from './project-policy.js';
|
|
3
|
+
import { type AutomationExecutor, type AutomationExecutorContext } from './types.js';
|
|
4
|
+
/** Runs one admitted automation through a fresh, persisted, preset-composed Harness Agent. */
|
|
5
|
+
export declare class HarnessAgentExecutor implements AutomationExecutor {
|
|
6
|
+
readonly kind = "agent";
|
|
7
|
+
private readonly ctx;
|
|
8
|
+
private readonly projectPolicy;
|
|
9
|
+
constructor(ctx: Context, projectPolicy: ProjectPolicy);
|
|
10
|
+
execute(context: AutomationExecutorContext): Promise<{
|
|
11
|
+
sessionId: string;
|
|
12
|
+
output?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=agent-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-executor.d.ts","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAwB,KAAK,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,YAAY,CAAA;AAgF1G,8FAA8F;AAC9F,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,QAAQ,CAAC,IAAI,WAAU;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;gBAEjC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa;IAKhD,OAAO,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA+EnG"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import { installModelSelection } from '@deepseek-ai/dsh-agent';
|
|
4
|
+
import { createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
5
|
+
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
6
|
+
import { ProjectPolicy } from './project-policy.js';
|
|
7
|
+
import { AUTOMATION_PLUGIN_ID } from './types.js';
|
|
8
|
+
class AgentRunError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(message, code, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
this.name = 'AgentRunError';
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function summarize(events, firstSeq) {
|
|
17
|
+
let started = false;
|
|
18
|
+
let text = '';
|
|
19
|
+
let reason;
|
|
20
|
+
for (const event of events) {
|
|
21
|
+
if (event.seq < firstSeq)
|
|
22
|
+
continue;
|
|
23
|
+
if (event.type === 'turn/start') {
|
|
24
|
+
started = true;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!started)
|
|
28
|
+
continue;
|
|
29
|
+
if (event.type === 'assistant/message') {
|
|
30
|
+
const joined = event.data.message.content
|
|
31
|
+
.filter((block) => block.type === 'text')
|
|
32
|
+
.map((block) => block.text)
|
|
33
|
+
.join('');
|
|
34
|
+
if (joined !== '')
|
|
35
|
+
text = joined;
|
|
36
|
+
}
|
|
37
|
+
if (event.type === 'turn/end')
|
|
38
|
+
reason = event.data.reason;
|
|
39
|
+
}
|
|
40
|
+
return reason === undefined ? { text } : { text, reason };
|
|
41
|
+
}
|
|
42
|
+
function failureFromReason(reason) {
|
|
43
|
+
if (reason === undefined)
|
|
44
|
+
return new AgentRunError('The agent produced no terminal turn outcome.', 'MISSING_TURN_OUTCOME');
|
|
45
|
+
if (reason.kind === 'error') {
|
|
46
|
+
return new AgentRunError(reason.error.message, reason.error.code);
|
|
47
|
+
}
|
|
48
|
+
if (reason.kind === 'blocked')
|
|
49
|
+
return new AgentRunError('The agent turn was blocked.', 'TURN_BLOCKED');
|
|
50
|
+
if (reason.kind === 'max-tokens')
|
|
51
|
+
return new AgentRunError('The agent reached its output-token limit.', 'TURN_MAX_TOKENS');
|
|
52
|
+
if (reason.kind === 'aborted')
|
|
53
|
+
return new AgentRunError('The agent turn was aborted.', 'TURN_ABORTED');
|
|
54
|
+
if (reason.kind === 'interrupted')
|
|
55
|
+
return new AgentRunError('The agent turn was interrupted by a previous host crash.', 'TURN_INTERRUPTED');
|
|
56
|
+
return new AgentRunError(`The agent ended with unsupported reason "${String(reason.kind)}".`, 'TURN_FAILED');
|
|
57
|
+
}
|
|
58
|
+
async function assertCanonicalDirectory(cwd) {
|
|
59
|
+
const [metadata, canonical] = await Promise.all([stat(cwd), realpath(cwd)]);
|
|
60
|
+
if (!metadata.isDirectory())
|
|
61
|
+
throw new AgentRunError(`Project path is not a directory: ${cwd}`, 'PROJECT_NOT_DIRECTORY');
|
|
62
|
+
if (canonical !== cwd) {
|
|
63
|
+
throw new AgentRunError(`Project path no longer resolves to its saved filesystem identity: expected ${cwd}, found ${canonical}`, 'PROJECT_IDENTITY_CHANGED');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function resolveSelection(ctx, run) {
|
|
67
|
+
const execution = run.snapshot.execution;
|
|
68
|
+
const current = ctx.agentDefaultModel.currentSelection();
|
|
69
|
+
const provider = execution.provider ?? current.provider;
|
|
70
|
+
const model = execution.model ?? current.model;
|
|
71
|
+
const reasoningEffort = execution.reasoningEffort === undefined
|
|
72
|
+
? execution.provider === undefined
|
|
73
|
+
? current.reasoningEffort
|
|
74
|
+
: undefined
|
|
75
|
+
: ReasoningEffortId(execution.reasoningEffort);
|
|
76
|
+
return {
|
|
77
|
+
provider,
|
|
78
|
+
model,
|
|
79
|
+
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Runs one admitted automation through a fresh, persisted, preset-composed Harness Agent. */
|
|
83
|
+
export class HarnessAgentExecutor {
|
|
84
|
+
kind = 'agent';
|
|
85
|
+
ctx;
|
|
86
|
+
projectPolicy;
|
|
87
|
+
constructor(ctx, projectPolicy) {
|
|
88
|
+
this.ctx = ctx;
|
|
89
|
+
this.projectPolicy = projectPolicy;
|
|
90
|
+
}
|
|
91
|
+
async execute(context) {
|
|
92
|
+
const { run, signal } = context;
|
|
93
|
+
const execution = run.snapshot.execution;
|
|
94
|
+
const authorizedCwd = await this.projectPolicy.authorize(execution.cwd);
|
|
95
|
+
await assertCanonicalDirectory(authorizedCwd);
|
|
96
|
+
if (signal.aborted)
|
|
97
|
+
throw signal.reason;
|
|
98
|
+
const preset = await this.ctx.agentPresets.resolve(execution.agentPreset);
|
|
99
|
+
if (preset.broken !== undefined) {
|
|
100
|
+
throw new AgentRunError(`Agent preset "${preset.id}" is broken: ${preset.broken}`, 'BROKEN_AGENT_PRESET');
|
|
101
|
+
}
|
|
102
|
+
this.ctx.permissionPresets.resolve(execution.permissionPreset);
|
|
103
|
+
const selection = resolveSelection(this.ctx, run);
|
|
104
|
+
const sessionId = SessionId(`session-${randomUUID()}`);
|
|
105
|
+
const handle = await this.ctx.agents.create({
|
|
106
|
+
sessionId,
|
|
107
|
+
meta: {
|
|
108
|
+
cwd: execution.cwd,
|
|
109
|
+
agentPreset: preset.id,
|
|
110
|
+
},
|
|
111
|
+
agentOptions: {
|
|
112
|
+
provider: selection.provider,
|
|
113
|
+
model: selection.model,
|
|
114
|
+
},
|
|
115
|
+
signal,
|
|
116
|
+
setup: async (agentCtx) => {
|
|
117
|
+
await this.ctx.agentPresets.mount(agentCtx, preset.id);
|
|
118
|
+
installModelSelection(agentCtx, {
|
|
119
|
+
current: selection,
|
|
120
|
+
assembled: undefined,
|
|
121
|
+
});
|
|
122
|
+
const agent = agentCtx.agent;
|
|
123
|
+
if (agent === undefined)
|
|
124
|
+
throw new AgentRunError('Agent setup context has no agent.', 'AGENT_SETUP_FAILED');
|
|
125
|
+
this.ctx.permissionPresets.set(agent.session, execution.permissionPreset);
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
const { agent } = handle;
|
|
129
|
+
const cancel = () => {
|
|
130
|
+
agent.cancel({
|
|
131
|
+
kind: 'hook',
|
|
132
|
+
reason: signal.reason instanceof Error ? signal.reason.message : 'automation run aborted',
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
signal.addEventListener('abort', cancel, { once: true });
|
|
136
|
+
try {
|
|
137
|
+
await context.attachSession(String(sessionId));
|
|
138
|
+
if (signal.aborted)
|
|
139
|
+
throw signal.reason;
|
|
140
|
+
await agent.whenIdle();
|
|
141
|
+
const firstSeq = agent.session.seq;
|
|
142
|
+
agent.followup(createUserMessage({
|
|
143
|
+
content: [
|
|
144
|
+
{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: run.snapshot.task.prompt,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
source: {
|
|
150
|
+
kind: 'plugin',
|
|
151
|
+
plugin: AUTOMATION_PLUGIN_ID,
|
|
152
|
+
},
|
|
153
|
+
}));
|
|
154
|
+
await agent.whenIdle();
|
|
155
|
+
if (signal.aborted)
|
|
156
|
+
throw signal.reason;
|
|
157
|
+
await this.ctx.sessions.flush(agent.session);
|
|
158
|
+
const outcome = summarize(agent.session.events, firstSeq);
|
|
159
|
+
if (outcome.reason?.kind !== 'completed')
|
|
160
|
+
throw failureFromReason(outcome.reason);
|
|
161
|
+
return {
|
|
162
|
+
sessionId: String(sessionId),
|
|
163
|
+
...(outcome.text === '' ? {} : { output: outcome.text }),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
signal.removeEventListener('abort', cancel);
|
|
168
|
+
await this.ctx.sessions.flush(agent.session).catch(() => undefined);
|
|
169
|
+
await handle.dispose().catch(() => undefined);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=agent-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-executor.js","sourceRoot":"","sources":["../src/agent-executor.ts"],"names":[],"mappings":"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"}
|
package/dist/cron.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class CronValidationError extends Error {
|
|
2
|
+
readonly code = "INVALID_CRON";
|
|
3
|
+
constructor(message: string, options?: ErrorOptions);
|
|
4
|
+
}
|
|
5
|
+
export declare function normalizeTimezone(value: string): string;
|
|
6
|
+
export declare function normalizeCron(value: string): string;
|
|
7
|
+
export declare function validateCron(cronValue: string, timezoneValue: string): {
|
|
8
|
+
cron: string;
|
|
9
|
+
timezone: string;
|
|
10
|
+
};
|
|
11
|
+
/** First occurrence strictly after `after`. */
|
|
12
|
+
export declare function nextCronOccurrence(cronValue: string, timezoneValue: string, after: Date): Date;
|
|
13
|
+
/** Latest occurrence at or before `at`; useful for latest-only misfire coalescing. */
|
|
14
|
+
export declare function latestCronOccurrence(cronValue: string, timezoneValue: string, at: Date): Date;
|
|
15
|
+
//# sourceMappingURL=cron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"AAEA,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,kBAAiB;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAeA;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAe9F;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,CAe7F"}
|
package/dist/cron.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { CronExpressionParser } from 'cron-parser';
|
|
2
|
+
export class CronValidationError extends Error {
|
|
3
|
+
code = 'INVALID_CRON';
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
this.name = 'CronValidationError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function normalizeTimezone(value) {
|
|
10
|
+
const timezone = value.trim();
|
|
11
|
+
if (timezone === '')
|
|
12
|
+
throw new CronValidationError('timezone must not be empty');
|
|
13
|
+
try {
|
|
14
|
+
return new Intl.DateTimeFormat('en-US', { timeZone: timezone }).resolvedOptions().timeZone;
|
|
15
|
+
}
|
|
16
|
+
catch (cause) {
|
|
17
|
+
throw new CronValidationError(`invalid IANA timezone "${timezone}"`, { cause });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function normalizeCron(value) {
|
|
21
|
+
const cron = value.trim().replace(/\s+/g, ' ');
|
|
22
|
+
if (cron.split(' ').length !== 5) {
|
|
23
|
+
throw new CronValidationError('cron must contain exactly five fields: minute hour day-of-month month day-of-week');
|
|
24
|
+
}
|
|
25
|
+
if (/\bH(?:\([^)]*\))?(?:\/\d+)?\b/.test(cron)) {
|
|
26
|
+
throw new CronValidationError('hashed H expressions are not supported because job schedules must be replay-deterministic');
|
|
27
|
+
}
|
|
28
|
+
return cron;
|
|
29
|
+
}
|
|
30
|
+
export function validateCron(cronValue, timezoneValue) {
|
|
31
|
+
const cron = normalizeCron(cronValue);
|
|
32
|
+
const timezone = normalizeTimezone(timezoneValue);
|
|
33
|
+
try {
|
|
34
|
+
CronExpressionParser.parse(cron, {
|
|
35
|
+
currentDate: new Date(),
|
|
36
|
+
tz: timezone,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (cause) {
|
|
40
|
+
throw new CronValidationError(`invalid cron expression "${cron}": ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
41
|
+
}
|
|
42
|
+
return { cron, timezone };
|
|
43
|
+
}
|
|
44
|
+
/** First occurrence strictly after `after`. */
|
|
45
|
+
export function nextCronOccurrence(cronValue, timezoneValue, after) {
|
|
46
|
+
const { cron, timezone } = validateCron(cronValue, timezoneValue);
|
|
47
|
+
try {
|
|
48
|
+
return CronExpressionParser.parse(cron, {
|
|
49
|
+
currentDate: after,
|
|
50
|
+
tz: timezone,
|
|
51
|
+
})
|
|
52
|
+
.next()
|
|
53
|
+
.toDate();
|
|
54
|
+
}
|
|
55
|
+
catch (cause) {
|
|
56
|
+
throw new CronValidationError(`cannot calculate the next occurrence for "${cron}" in ${timezone}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Latest occurrence at or before `at`; useful for latest-only misfire coalescing. */
|
|
60
|
+
export function latestCronOccurrence(cronValue, timezoneValue, at) {
|
|
61
|
+
const { cron, timezone } = validateCron(cronValue, timezoneValue);
|
|
62
|
+
try {
|
|
63
|
+
return CronExpressionParser.parse(cron, {
|
|
64
|
+
currentDate: new Date(at.getTime() + 1),
|
|
65
|
+
tz: timezone,
|
|
66
|
+
})
|
|
67
|
+
.prev()
|
|
68
|
+
.toDate();
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
throw new CronValidationError(`cannot calculate the previous occurrence for "${cron}" in ${timezone}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=cron.js.map
|
package/dist/cron.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { AutomationServiceApi } from './types.js';
|
|
3
|
+
interface HttpLogger {
|
|
4
|
+
warn(message: string, ...args: unknown[]): void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createAutomationHttpHandler(service: AutomationServiceApi, prefix: string, logger: HttpLogger): (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,KAAK,EAAiB,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAIrE,UAAU,UAAU;IAClB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAChD;AA6FD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,GACjB,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAsGvE"}
|