@deepseek-ai/dsh-schedule 0.0.1-rc.3

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.
@@ -0,0 +1,291 @@
1
+ const MIN_FOUR_DIGIT_YEAR_MS = Date.parse("0001-01-01T00:00:00.000Z");
2
+ const MAX_FOUR_DIGIT_YEAR_MS = Date.parse("9999-12-31T23:59:59.999Z");
3
+ const UTC_INSTANT = /^(?!0000)\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d\.\d{3}Z$/;
4
+ new RegExp(String.raw`^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})` + String.raw`T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})` + String.raw`(?:\.(?<fraction>\d{1,3}))?(?<zone>Z|(?<sign>[+-])` + String.raw`(?<offsetHour>\d{2}):(?<offsetMinute>\d{2}))$`);
5
+ /** Error from malformed or transition-invalid durable Schedule data. */
6
+ var ScheduleLogError = class extends Error {
7
+ /** Stable machine-readable error code. */
8
+ code = "corrupt_schedule_log";
9
+ /**
10
+ * Construct a durable-log failure.
11
+ * @param message - Package-specific violated invariant.
12
+ */
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = "ScheduleLogError";
16
+ }
17
+ };
18
+ /**
19
+ * Brand a raw session-local id without changing its runtime value.
20
+ * @param value - Raw session-local id.
21
+ * @returns The same string with the Schedule brand.
22
+ */
23
+ function ScheduleId(value) {
24
+ return value;
25
+ }
26
+ /** Whether an unknown value is a non-array object. */
27
+ function isRecord(value) {
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ }
30
+ /** Require exactly the named durable object keys. */
31
+ function hasExactKeys(value, expected) {
32
+ const keys = Object.keys(value).sort();
33
+ const wanted = [...expected].sort();
34
+ return keys.length === wanted.length && keys.every((key, index) => key === wanted[index]);
35
+ }
36
+ /** Validate one stable session-local id at the durable boundary. */
37
+ function decodeId(value) {
38
+ if (typeof value !== "string" || value.length === 0 || value.trim() !== value) throw new ScheduleLogError("schedule id must be a non-empty string without surrounding whitespace");
39
+ return ScheduleId(value);
40
+ }
41
+ /** Validate one canonical four-digit-year UTC instant. */
42
+ function decodeInstant(value) {
43
+ if (typeof value !== "string" || !UTC_INSTANT.test(value)) throw new ScheduleLogError("scheduledAt must be a canonical four-digit-year RFC 3339 UTC instant");
44
+ const epoch = Date.parse(value);
45
+ if (!Number.isFinite(epoch) || new Date(epoch).toISOString() !== value) throw new ScheduleLogError("scheduledAt is not a real UTC calendar instant");
46
+ return value;
47
+ }
48
+ /** Decode the exact v1 after record shape. */
49
+ function decodeAfterRecord(value) {
50
+ if (!isRecord(value) || !hasExactKeys(value, [
51
+ "id",
52
+ "kind",
53
+ "prompt",
54
+ "afterSeconds",
55
+ "scheduledAt"
56
+ ])) throw new ScheduleLogError("after schedule must contain exactly id, kind, prompt, afterSeconds, and scheduledAt");
57
+ const prompt = value["prompt"];
58
+ if (typeof prompt !== "string" || prompt.length === 0 || prompt.trim() !== prompt) throw new ScheduleLogError("after prompt must be non-empty and already trimmed");
59
+ const afterSeconds = value["afterSeconds"];
60
+ if (!Number.isSafeInteger(afterSeconds) || afterSeconds <= 0) throw new ScheduleLogError("afterSeconds must be a positive safe integer");
61
+ return Object.freeze({
62
+ id: decodeId(value["id"]),
63
+ kind: "after",
64
+ prompt,
65
+ afterSeconds,
66
+ scheduledAt: decodeInstant(value["scheduledAt"])
67
+ });
68
+ }
69
+ /** Decode the exact v1 absolute one-shot record shape. */
70
+ function decodeAtRecord(value) {
71
+ if (!isRecord(value) || !hasExactKeys(value, [
72
+ "id",
73
+ "kind",
74
+ "prompt",
75
+ "scheduledAt"
76
+ ])) throw new ScheduleLogError("at schedule must contain exactly id, kind, prompt, and scheduledAt");
77
+ const prompt = value["prompt"];
78
+ if (typeof prompt !== "string" || prompt.length === 0 || prompt.trim() !== prompt) throw new ScheduleLogError("at prompt must be non-empty and already trimmed");
79
+ return Object.freeze({
80
+ id: decodeId(value["id"]),
81
+ kind: "at",
82
+ prompt,
83
+ scheduledAt: decodeInstant(value["scheduledAt"])
84
+ });
85
+ }
86
+ /** Decode the exact v1 fixed-rate record shape. */
87
+ function decodeEveryRecord(value) {
88
+ if (!isRecord(value) || !hasExactKeys(value, [
89
+ "id",
90
+ "kind",
91
+ "prompt",
92
+ "everySeconds",
93
+ "scheduledAt"
94
+ ])) throw new ScheduleLogError("every schedule must contain exactly id, kind, prompt, everySeconds, and scheduledAt");
95
+ const prompt = value["prompt"];
96
+ if (typeof prompt !== "string" || prompt.length === 0 || prompt.trim() !== prompt) throw new ScheduleLogError("every prompt must be non-empty and already trimmed");
97
+ const everySeconds = value["everySeconds"];
98
+ const interval = typeof everySeconds === "number" ? everySeconds * 1e3 : NaN;
99
+ if (!Number.isSafeInteger(everySeconds) || everySeconds < 300 || !Number.isSafeInteger(interval)) throw new ScheduleLogError(`everySeconds must be a safe integer of at least 300`);
100
+ return Object.freeze({
101
+ id: decodeId(value["id"]),
102
+ kind: "every",
103
+ prompt,
104
+ everySeconds,
105
+ scheduledAt: decodeInstant(value["scheduledAt"])
106
+ });
107
+ }
108
+ /** Decode one current durable record variant by its exact discriminator. */
109
+ function decodeScheduleRecord(value) {
110
+ if (!isRecord(value)) throw new ScheduleLogError("schedule record must be an object");
111
+ switch (value["kind"]) {
112
+ case "after": return decodeAfterRecord(value);
113
+ case "at": return decodeAtRecord(value);
114
+ case "every": return decodeEveryRecord(value);
115
+ default: throw new ScheduleLogError("v1 schedule kind must be \"after\", \"at\", or \"every\"");
116
+ }
117
+ }
118
+ /**
119
+ * Decode one strict version-1 `schedule/change` payload.
120
+ * @param value - Untrusted durable JSON value.
121
+ * @returns Detached, frozen Schedule change.
122
+ */
123
+ function decodeScheduleChange(value) {
124
+ if (!isRecord(value)) throw new ScheduleLogError("schedule/change payload must be an object");
125
+ if (value["version"] !== 1) throw new ScheduleLogError("schedule/change version must be 1");
126
+ switch (value["operation"]) {
127
+ case "create":
128
+ if (!hasExactKeys(value, [
129
+ "version",
130
+ "operation",
131
+ "schedule"
132
+ ])) throw new ScheduleLogError("schedule create must contain exactly version, operation, and schedule");
133
+ return Object.freeze({
134
+ version: 1,
135
+ operation: "create",
136
+ schedule: decodeScheduleRecord(value["schedule"])
137
+ });
138
+ case "delete":
139
+ if (!hasExactKeys(value, [
140
+ "version",
141
+ "operation",
142
+ "id"
143
+ ])) throw new ScheduleLogError("schedule delete must contain exactly version, operation, and id");
144
+ return Object.freeze({
145
+ version: 1,
146
+ operation: "delete",
147
+ id: decodeId(value["id"])
148
+ });
149
+ case "dispatch":
150
+ if (hasExactKeys(value, [
151
+ "version",
152
+ "operation",
153
+ "id"
154
+ ])) return Object.freeze({
155
+ version: 1,
156
+ operation: "dispatch",
157
+ id: decodeId(value["id"])
158
+ });
159
+ if (hasExactKeys(value, [
160
+ "version",
161
+ "operation",
162
+ "id",
163
+ "acceptedAt"
164
+ ])) return Object.freeze({
165
+ version: 1,
166
+ operation: "dispatch",
167
+ id: decodeId(value["id"]),
168
+ acceptedAt: decodeInstant(value["acceptedAt"])
169
+ });
170
+ throw new ScheduleLogError("schedule dispatch must contain id and optional acceptedAt only");
171
+ default: throw new ScheduleLogError("schedule/change operation must be create, delete, or dispatch");
172
+ }
173
+ }
174
+ /**
175
+ * Resolve one fixed-rate decision without enumerating missed occurrences.
176
+ * @param record - Active record whose target is the earliest unaccepted occurrence.
177
+ * @param acceptedAt - Wall-clock decision time in epoch milliseconds.
178
+ * @returns The latest due occurrence and first strictly future target, if representable.
179
+ */
180
+ function resolveEveryOccurrence(record, acceptedAt) {
181
+ const target = Date.parse(record.scheduledAt);
182
+ const interval = record.everySeconds * 1e3;
183
+ if (!Number.isSafeInteger(acceptedAt) || acceptedAt < MIN_FOUR_DIGIT_YEAR_MS || acceptedAt > MAX_FOUR_DIGIT_YEAR_MS) throw new ScheduleLogError("every acceptedAt must be a representable four-digit-year instant");
184
+ if (!Number.isSafeInteger(interval) || interval <= 0) throw new ScheduleLogError("every interval milliseconds must be a positive safe integer");
185
+ if (acceptedAt < target) throw new ScheduleLogError("every dispatch cannot precede the active scheduledAt");
186
+ const occurrence = target + Math.floor((acceptedAt - target) / interval) * interval;
187
+ /* v8 ignore next -- bounded operands and a quotient-derived product stay safe. */
188
+ if (!Number.isSafeInteger(occurrence) || occurrence < target || occurrence > acceptedAt) throw new ScheduleLogError("every occurrence arithmetic must stay within the accepted interval");
189
+ const occurrenceAt = new Date(occurrence).toISOString();
190
+ const next = occurrence + interval;
191
+ if (!Number.isSafeInteger(next) || next > MAX_FOUR_DIGIT_YEAR_MS) return Object.freeze({ occurrenceAt });
192
+ return Object.freeze({
193
+ occurrenceAt,
194
+ nextScheduledAt: new Date(next).toISOString()
195
+ });
196
+ }
197
+ /** Apply one decoded dispatch to its exact active record. */
198
+ function dispatchedRecord(record, change) {
199
+ const hasAcceptedAt = "acceptedAt" in change;
200
+ if (record.kind !== "every") {
201
+ if (hasAcceptedAt) throw new ScheduleLogError("one-shot dispatch must not contain acceptedAt");
202
+ return;
203
+ }
204
+ if (!hasAcceptedAt) throw new ScheduleLogError("every dispatch must contain acceptedAt");
205
+ const occurrence = resolveEveryOccurrence(record, Date.parse(change.acceptedAt));
206
+ return occurrence.nextScheduledAt === void 0 ? void 0 : Object.freeze({
207
+ ...record,
208
+ scheduledAt: occurrence.nextScheduledAt
209
+ });
210
+ }
211
+ /**
212
+ * Fold the package-owned stream after the durable fork seed boundary.
213
+ * @param events - Complete ordered session log or candidate-extended log.
214
+ * @param seedLength - Inherited prefix length excluded from child ownership.
215
+ * @returns Active records and all previously used ids.
216
+ */
217
+ function foldScheduleEvents(events, seedLength = 0) {
218
+ if (!Number.isSafeInteger(seedLength) || seedLength < 0 || seedLength > events.length) throw new ScheduleLogError("schedule seedLength must be within the supplied event log");
219
+ const active = /* @__PURE__ */ new Map();
220
+ const seen = /* @__PURE__ */ new Set();
221
+ for (const event of events.slice(seedLength)) {
222
+ if (event.type !== "schedule/change") continue;
223
+ const change = decodeScheduleChange(event.data);
224
+ switch (change.operation) {
225
+ case "create":
226
+ if (seen.has(change.schedule.id)) throw new ScheduleLogError(`schedule id ${JSON.stringify(change.schedule.id)} was reused`);
227
+ seen.add(change.schedule.id);
228
+ active.set(change.schedule.id, change.schedule);
229
+ break;
230
+ case "delete":
231
+ if (!active.delete(change.id)) throw new ScheduleLogError(`schedule delete targets inactive id ${JSON.stringify(change.id)}`);
232
+ break;
233
+ case "dispatch": {
234
+ const record = active.get(change.id);
235
+ if (record === void 0) throw new ScheduleLogError(`schedule dispatch targets inactive id ${JSON.stringify(change.id)}`);
236
+ const next = dispatchedRecord(record, change);
237
+ if (next === void 0) active.delete(change.id);
238
+ else active.set(change.id, next);
239
+ break;
240
+ }
241
+ /* v8 ignore next 3 -- decodeScheduleChange returns a closed operation union. */
242
+ default: throw new ScheduleLogError(`unknown decoded schedule change ${String(change)}`);
243
+ }
244
+ }
245
+ return Object.freeze({
246
+ active: Object.freeze([...active.values()]),
247
+ seenIds: Object.freeze([...seen])
248
+ });
249
+ }
250
+ //#endregion
251
+ //#region lib/types/invariant.js
252
+ /**
253
+ * Package-owned strict Schedule stream invariant.
254
+ * @module @deepseek-ai/dsh-schedule/invariant
255
+ */
256
+ const PACKAGE_NAME = "@deepseek-ai/dsh-schedule";
257
+ /** Cordis invariant-companion plugin name. */
258
+ const name = "tool-schedule-invariant";
259
+ /** Service required before reserving this package's invariant ownership. */
260
+ const inject = ["invariants"];
261
+ /** Validate a complete exact-session stream under its fork suffix policy. */
262
+ function validate(events, seedLength, fail) {
263
+ try {
264
+ foldScheduleEvents(events, seedLength);
265
+ } catch (error) {
266
+ /* v8 ignore next -- foldScheduleEvents normalizes every rejected stream to ScheduleLogError. */
267
+ if (!(error instanceof ScheduleLogError)) throw error;
268
+ fail(error.message);
269
+ }
270
+ }
271
+ /** Install replay and pre-append validation for the owned event stream. */
272
+ const install = Object.assign((ctx, fail) => {
273
+ for (const session of ctx.sessions.list()) validate(session.events, session.header.seedLength ?? 0, fail);
274
+ ctx.on("session/created", (session) => {
275
+ validate(session.events, session.header.seedLength ?? 0, fail);
276
+ }, { global: true });
277
+ ctx.on("internal/dispatch", (_mode, eventName, args) => {
278
+ if (eventName !== "session/event") return;
279
+ const [session, event] = args;
280
+ if (event.type !== "schedule/change") return;
281
+ validate([...session.events, event], session.header.seedLength ?? 0, fail);
282
+ }, { global: true });
283
+ }, { inject: ["sessions"] });
284
+ /**
285
+ * Register the package-owned invariant companion.
286
+ * @param ctx - Cordis context carrying the invariant registry.
287
+ * @returns Exact registration disposer after child setup succeeds.
288
+ */
289
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
290
+ //#endregion
291
+ export { apply, inject, name };
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Strict Schedule decoding, replay, time validation, and framing.
3
+ * @module @deepseek-ai/dsh-schedule
4
+ */
5
+ import type { SessionEvent } from '@deepseek-ai/dsh-session';
6
+ import type { AfterScheduleRecord, AtInput, AtScheduleRecord, EveryScheduleRecord, OneShotScheduleRecord, ScheduleChange, ScheduleId as ScheduleIdType, ScheduleRecord, ScheduleView } from './types.ts';
7
+ /** Durable Schedule protocol version implemented by this package. */
8
+ export declare const SCHEDULE_CHANGE_VERSION: 1;
9
+ /** Fixed v1 lower bound for a fixed-rate reminder. */
10
+ export declare const MIN_EVERY_INTERVAL_SECONDS = 300;
11
+ /** Error from malformed or transition-invalid durable Schedule data. */
12
+ export declare class ScheduleLogError extends Error {
13
+ /** Stable machine-readable error code. */
14
+ readonly code: "corrupt_schedule_log";
15
+ /**
16
+ * Construct a durable-log failure.
17
+ * @param message - Package-specific violated invariant.
18
+ */
19
+ constructor(message: string);
20
+ }
21
+ /** Error from a model-supplied Schedule rule that cannot become a record. */
22
+ export declare class ScheduleInputError extends Error {
23
+ /** Stable public Schedule input code. */
24
+ readonly code: 'invalid_prompt' | 'invalid_rule' | 'invalid_time_zone' | 'not_future' | 'time_out_of_range' | 'frequency_too_high';
25
+ /**
26
+ * Construct a stable input failure.
27
+ * @param code - Public Schedule error discriminator.
28
+ * @param message - Stable public diagnostic.
29
+ * @param options - Optional contained implementation cause.
30
+ */
31
+ constructor(code: 'invalid_prompt' | 'invalid_rule' | 'invalid_time_zone' | 'not_future' | 'time_out_of_range' | 'frequency_too_high', message: string, options?: ErrorOptions);
32
+ }
33
+ /** Pure replay result, retaining active create order and every used id. */
34
+ export interface FoldedSchedules {
35
+ /** Active records in their original create order. */
36
+ readonly active: readonly ScheduleRecord[];
37
+ /** Every id ever created in this session-local suffix. */
38
+ readonly seenIds: readonly ScheduleIdType[];
39
+ }
40
+ /** One latest-only fixed-rate decision derived without enumerating a backlog. */
41
+ export interface EveryOccurrence {
42
+ /** Latest anchor-aligned occurrence due at the decision time. */
43
+ readonly occurrenceAt: string;
44
+ /** First anchor-aligned target after the decision, or exhaustion. */
45
+ readonly nextScheduledAt?: string;
46
+ }
47
+ /**
48
+ * Brand a raw session-local id without changing its runtime value.
49
+ * @param value - Raw session-local id.
50
+ * @returns The same string with the Schedule brand.
51
+ */
52
+ export declare function ScheduleId(value: string): ScheduleIdType;
53
+ /**
54
+ * Validate and canonicalize one raw IANA time-zone selector.
55
+ * @param value - Candidate `UTC` or IANA Area/Location name.
56
+ * @returns The runtime's canonical IANA name.
57
+ */
58
+ export declare function canonicalizeTimeZone(value: string): string;
59
+ /**
60
+ * Decode one strict version-1 `schedule/change` payload.
61
+ * @param value - Untrusted durable JSON value.
62
+ * @returns Detached, frozen Schedule change.
63
+ */
64
+ export declare function decodeScheduleChange(value: unknown): ScheduleChange;
65
+ /**
66
+ * Resolve one fixed-rate decision without enumerating missed occurrences.
67
+ * @param record - Active record whose target is the earliest unaccepted occurrence.
68
+ * @param acceptedAt - Wall-clock decision time in epoch milliseconds.
69
+ * @returns The latest due occurrence and first strictly future target, if representable.
70
+ */
71
+ export declare function resolveEveryOccurrence(record: EveryScheduleRecord, acceptedAt: number): EveryOccurrence;
72
+ /**
73
+ * Fold the package-owned stream after the durable fork seed boundary.
74
+ * @param events - Complete ordered session log or candidate-extended log.
75
+ * @param seedLength - Inherited prefix length excluded from child ownership.
76
+ * @returns Active records and all previously used ids.
77
+ */
78
+ export declare function foldScheduleEvents(events: readonly SessionEvent[], seedLength?: number): FoldedSchedules;
79
+ /**
80
+ * Allocate the next readable id without reusing any prior session-local id.
81
+ * @param folded - Fold containing every previously created id.
82
+ * @returns A fresh `schedule-N` identity.
83
+ */
84
+ export declare function allocateScheduleId(folded: FoldedSchedules): ScheduleIdType;
85
+ /**
86
+ * Validate a model after rule and compute its durable target.
87
+ * @param id - Already allocated session-local id.
88
+ * @param prompt - Reminder content supplied at creation.
89
+ * @param afterSeconds - Requested positive delay.
90
+ * @param now - Single creation-time wall-clock sample in epoch milliseconds.
91
+ * @returns Frozen durable after record.
92
+ */
93
+ export declare function createAfterScheduleRecord(id: ScheduleIdType, prompt: string, afterSeconds: number, now: number): AfterScheduleRecord;
94
+ /**
95
+ * Validate an absolute selector and compute its sole durable UTC target.
96
+ * @param id - Already allocated session-local id.
97
+ * @param prompt - Reminder content supplied at creation.
98
+ * @param at - Explicit-offset instant or structured local calendar value.
99
+ * @param now - Single creation-time wall-clock sample in epoch milliseconds.
100
+ * @returns Frozen durable absolute one-shot record.
101
+ */
102
+ export declare function createAtScheduleRecord(id: ScheduleIdType, prompt: string, at: AtInput, now: number): AtScheduleRecord;
103
+ /**
104
+ * Validate a fixed-rate selector and compute its first creation-aligned target.
105
+ * @param id - Already allocated session-local id.
106
+ * @param prompt - Reminder content supplied at creation.
107
+ * @param everySeconds - Requested fixed safe-integer interval.
108
+ * @param now - Single creation-time wall-clock sample in epoch milliseconds.
109
+ * @returns Frozen durable fixed-rate record.
110
+ */
111
+ export declare function createEveryScheduleRecord(id: ScheduleIdType, prompt: string, everySeconds: number, now: number): EveryScheduleRecord;
112
+ /**
113
+ * Derive one execution-local management view.
114
+ * @param record - Active durable record.
115
+ * @param now - Wall-clock sample used for its timing state.
116
+ * @returns Complete session-local view.
117
+ */
118
+ export declare function scheduleView(record: ScheduleRecord, now: number): ScheduleView;
119
+ /**
120
+ * Render the fixed injection-resistant model framing for a due reminder.
121
+ * @param record - Due active record.
122
+ * @returns Stable model-visible text with JSON-escaped dynamic fields.
123
+ */
124
+ export declare function renderReminderFraming(record: OneShotScheduleRecord): string;
125
+ /**
126
+ * Render one injection-resistant fixed-rate batch in target and create order.
127
+ * @param reminders - Complete admitted batch with one latest occurrence per record.
128
+ * @returns Stable model-visible text whose dynamic payload is canonical JSON.
129
+ */
130
+ export declare function renderEveryReminderBatchFraming(reminders: readonly {
131
+ readonly record: EveryScheduleRecord;
132
+ readonly occurrenceAt: string;
133
+ }[]): string;
134
+ //# sourceMappingURL=domain.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Agent-scoped durable one-shot and fixed-rate reminders over the session event log.
3
+ * @module @deepseek-ai/dsh-schedule
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ export type * from './types.ts';
7
+ export { SCHEDULE_CHANGE_VERSION, MIN_EVERY_INTERVAL_SECONDS, ScheduleId, ScheduleInputError, ScheduleLogError, allocateScheduleId, createAfterScheduleRecord, createAtScheduleRecord, createEveryScheduleRecord, decodeScheduleChange, foldScheduleEvents, renderReminderFraming, renderEveryReminderBatchFraming, resolveEveryOccurrence, scheduleView, } from './domain.ts';
8
+ export { registerScheduleTools } from './tools.ts';
9
+ /** Cordis function-plugin name. */
10
+ export declare const name = "schedule";
11
+ /** Services required before future root agents can receive Schedule. */
12
+ export declare const inject: string[];
13
+ /** Install Schedule only for root agents published after this plugin loads. */
14
+ export declare function apply(ctx: Context): void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned strict Schedule stream invariant.
3
+ * @module @deepseek-ai/dsh-schedule/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis invariant-companion plugin name. */
7
+ export declare const name = "tool-schedule-invariant";
8
+ /** Service required before reserving this package's invariant ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register the package-owned invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant registry.
13
+ * @returns Exact registration disposer after child setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1,19 @@
1
+ /** Schedule-owned use of the shared session durability barrier. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { Session } from '@deepseek-ai/dsh-session';
4
+ /** Failure to prove that the current live prefix reached a persistence listener. */
5
+ export declare class SchedulePersistenceError extends Error {
6
+ /**
7
+ * Construct a contained persistence failure.
8
+ * @param cause - Rejection returned by the shared barrier, when present.
9
+ */
10
+ constructor(cause?: unknown);
11
+ }
12
+ /**
13
+ * Require one successful shared persistence checkpoint.
14
+ * @param ctx - Context carrying the live session store.
15
+ * @param session - Exact live session to checkpoint.
16
+ * @returns After at least one listener explicitly acknowledges completed durability work.
17
+ */
18
+ export declare function flushSchedulePersistence(ctx: Context, session: Session): Promise<void>;
19
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Disposable live timer projection for one exact root agent.
3
+ * @module @deepseek-ai/dsh-schedule
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ import type { Agent } from '@deepseek-ai/dsh-agent';
7
+ /** Largest delay that Node timers represent without clamping. */
8
+ export declare const MAX_TIMER_DELAY_MS = 2147483647;
9
+ /** One process-local, disposable projection of an exact agent's durable schedules. */
10
+ export declare class ScheduleRuntime {
11
+ private readonly ctx;
12
+ private readonly agent;
13
+ private readonly stop;
14
+ private timer;
15
+ private idleWait;
16
+ private run;
17
+ private requested;
18
+ private stopping;
19
+ private faulted;
20
+ private disposal;
21
+ /**
22
+ * Construct an inactive runtime; {@link start} begins the first preflight.
23
+ * @param ctx - Global service context.
24
+ * @param agent - Exact live root agent.
25
+ */
26
+ constructor(ctx: Context, agent: Agent);
27
+ /** Begin the initial durability preflight and timer derivation. */
28
+ start(): void;
29
+ /** Recompute the live projection after a committed mutation or idle transition. */
30
+ requestDrive(): void;
31
+ /** Stop future work, cancel timers, and await every outstanding runtime promise. */
32
+ dispose(): Promise<void>;
33
+ /** Drain coalesced triggers serially. */
34
+ private runRequested;
35
+ /** Retire one exact run and honor a trigger that landed during its final microtask. */
36
+ private retire;
37
+ /** Whether this exact root lifecycle remains authoritative. */
38
+ private isLive;
39
+ /** Whether this runtime may start or continue Schedule work. */
40
+ private isRunnable;
41
+ /** Cancel the currently armed timer, if any. */
42
+ private clearTimer;
43
+ /** Arm one bounded timer segment; every wake rechecks the wall clock. */
44
+ private arm;
45
+ /** Await one public idle boundary without holding admission or creating a retry timer. */
46
+ private waitForIdle;
47
+ /** Fold the current exact runtime suffix and contain a corrupt durable stream. */
48
+ private readFolded;
49
+ /** Contain an invalid wall-clock decision without permanently faulting this runtime. */
50
+ private decide;
51
+ /** Preflight, fold, arm, or dispatch the next one-shot or fixed-rate batch. */
52
+ private driveOnce;
53
+ }
54
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Agent-scoped Schedule management tools over the durable session fold.
3
+ * @module @deepseek-ai/dsh-schedule
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ import type { Agent } from '@deepseek-ai/dsh-agent';
7
+ /**
8
+ * Register all three Schedule tools in one exact agent scope.
9
+ * @param rootCtx - Global service context owning sessions and durability.
10
+ * @param toolCtx - Exact agent-scoped context receiving the definitions.
11
+ * @param agent - Exact live owner whose session the tools mutate.
12
+ * @param onDurableChange - Called after every successful preflight and again after a create or actual delete barrier succeeds.
13
+ * @returns Idempotent aggregate disposer for the three registrations.
14
+ */
15
+ export declare function registerScheduleTools(rootCtx: Context, toolCtx: Context, agent: Agent, onDurableChange: () => void): () => void;
16
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1,10 @@
1
+ /** Agent-scoped serialization for Schedule reads and durable mutations. */
2
+ import type { Agent } from '@deepseek-ai/dsh-agent';
3
+ /**
4
+ * Run one complete Schedule transaction after its exact Agent's prior transaction.
5
+ * @param agent - Exact Schedule owner and serialization key.
6
+ * @param operation - Complete preflight, fold, mutation, and postflight operation.
7
+ * @returns The operation result after exclusive execution.
8
+ */
9
+ export declare function runScheduleTransaction<T>(agent: Agent, operation: () => Promise<T>): Promise<T>;
10
+ //# sourceMappingURL=transaction.d.ts.map