@sellable/mcp 0.1.560 → 0.1.561-hermes031.202607110338

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/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
@@ -0,0 +1,34 @@
1
+ export type RefillDateWindowSource = "default_scheduler_forward" | "horizon_send_days" | "until_date" | "target_date";
2
+ export type NormalizedRefillDateSelector = {
3
+ source: RefillDateWindowSource;
4
+ targetDate: string | null;
5
+ untilDate: string | null;
6
+ horizonSendDays: number | null;
7
+ };
8
+ export type RefillRunDateWindow = NormalizedRefillDateSelector & {
9
+ version: 1;
10
+ selectedDates: string[];
11
+ senderWindows?: Array<{
12
+ senderId: string | null;
13
+ timeZone: string | null;
14
+ selectedDates: string[];
15
+ }>;
16
+ };
17
+ type DateSelectorInput = {
18
+ targetDate?: unknown;
19
+ untilDate?: unknown;
20
+ horizonSendDays?: unknown;
21
+ };
22
+ export declare function normalizeRefillDateSelector(input: DateSelectorInput): NormalizedRefillDateSelector;
23
+ export declare function refillDateSelectorBody(selector: NormalizedRefillDateSelector): {
24
+ targetDate?: string;
25
+ untilDate?: string;
26
+ horizonSendDays?: number;
27
+ };
28
+ export declare function dateWindowFromSelector(selector: NormalizedRefillDateSelector): RefillRunDateWindow;
29
+ export declare function dateWindowFromPlan(plan: Record<string, unknown>, selector: NormalizedRefillDateSelector): RefillRunDateWindow;
30
+ export declare function dateWindowFromRunState(runState: unknown): RefillRunDateWindow | null;
31
+ export declare function selectorFromDateWindow(window: RefillRunDateWindow): NormalizedRefillDateSelector;
32
+ export declare function dateSelectorMatchesWindow(selector: NormalizedRefillDateSelector, window: RefillRunDateWindow): boolean;
33
+ export declare function schedulerSweepTargetDates(window: RefillRunDateWindow): string[];
34
+ export {};
@@ -0,0 +1,210 @@
1
+ function isRecord(value) {
2
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3
+ }
4
+ function stringValue(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : null;
6
+ }
7
+ function numberValue(value) {
8
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
9
+ }
10
+ function arrayValue(value) {
11
+ return Array.isArray(value) ? value : [];
12
+ }
13
+ function isValidDateKey(value) {
14
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value))
15
+ return false;
16
+ const [year, month, day] = value.split("-").map(Number);
17
+ const date = new Date(Date.UTC(year, month - 1, day));
18
+ return (date.getUTCFullYear() === year &&
19
+ date.getUTCMonth() === month - 1 &&
20
+ date.getUTCDate() === day);
21
+ }
22
+ function normalizeDateKey(value, field) {
23
+ if (value === undefined || value === null || value === "")
24
+ return null;
25
+ if (typeof value !== "string") {
26
+ throw new Error(`${field} must be a string in YYYY-MM-DD format.`);
27
+ }
28
+ const trimmed = value.trim();
29
+ if (!isValidDateKey(trimmed)) {
30
+ throw new Error(`${field} must be a valid YYYY-MM-DD calendar date.`);
31
+ }
32
+ return trimmed;
33
+ }
34
+ function normalizeHorizonSendDays(value) {
35
+ if (value === undefined)
36
+ return null;
37
+ if (typeof value !== "number" ||
38
+ !Number.isInteger(value) ||
39
+ value < 1 ||
40
+ value > 7) {
41
+ throw new Error("horizonSendDays must be an integer between 1 and 7.");
42
+ }
43
+ return value;
44
+ }
45
+ export function normalizeRefillDateSelector(input) {
46
+ const targetDate = normalizeDateKey(input.targetDate, "targetDate");
47
+ const untilDate = normalizeDateKey(input.untilDate, "untilDate");
48
+ const horizonSendDays = normalizeHorizonSendDays(input.horizonSendDays);
49
+ if (targetDate) {
50
+ return {
51
+ source: "target_date",
52
+ targetDate,
53
+ untilDate: null,
54
+ horizonSendDays: null,
55
+ };
56
+ }
57
+ if (untilDate) {
58
+ return {
59
+ source: "until_date",
60
+ targetDate: null,
61
+ untilDate,
62
+ horizonSendDays: null,
63
+ };
64
+ }
65
+ if (horizonSendDays !== null) {
66
+ return {
67
+ source: "horizon_send_days",
68
+ targetDate: null,
69
+ untilDate: null,
70
+ horizonSendDays,
71
+ };
72
+ }
73
+ return {
74
+ source: "default_scheduler_forward",
75
+ targetDate: null,
76
+ untilDate: null,
77
+ horizonSendDays: null,
78
+ };
79
+ }
80
+ export function refillDateSelectorBody(selector) {
81
+ if (selector.source === "target_date" && selector.targetDate) {
82
+ return { targetDate: selector.targetDate };
83
+ }
84
+ if (selector.source === "until_date" && selector.untilDate) {
85
+ return { untilDate: selector.untilDate };
86
+ }
87
+ if (selector.source === "horizon_send_days" &&
88
+ selector.horizonSendDays !== null) {
89
+ return { horizonSendDays: selector.horizonSendDays };
90
+ }
91
+ return {};
92
+ }
93
+ export function dateWindowFromSelector(selector) {
94
+ return {
95
+ version: 1,
96
+ ...selector,
97
+ selectedDates: selector.targetDate ? [selector.targetDate] : [],
98
+ };
99
+ }
100
+ function selectedDatesFromPlan(plan) {
101
+ const packet = isRecord(plan.packet) ? plan.packet : {};
102
+ const target = isRecord(packet.target) ? packet.target : {};
103
+ const window = isRecord(target.window) ? target.window : {};
104
+ const senderWindows = arrayValue(window.senderWindows).filter(isRecord);
105
+ const fromWindows = senderWindows.flatMap((senderWindow) => arrayValue(senderWindow.selectedDates)
106
+ .map((entry) => stringValue(entry))
107
+ .filter((entry) => Boolean(entry)));
108
+ if (fromWindows.length > 0)
109
+ return Array.from(new Set(fromWindows)).sort();
110
+ const senderRefillPlans = arrayValue(target.senderRefillPlans).filter(isRecord);
111
+ return Array.from(new Set(senderRefillPlans.flatMap((senderPlan) => {
112
+ const horizon = isRecord(senderPlan.horizon) ? senderPlan.horizon : {};
113
+ return arrayValue(horizon.selectedDays)
114
+ .filter(isRecord)
115
+ .map((day) => stringValue(day.date))
116
+ .filter((entry) => Boolean(entry));
117
+ }))).sort();
118
+ }
119
+ function senderWindowsFromPlan(plan) {
120
+ const packet = isRecord(plan.packet) ? plan.packet : {};
121
+ const target = isRecord(packet.target) ? packet.target : {};
122
+ const window = isRecord(target.window) ? target.window : {};
123
+ return arrayValue(window.senderWindows)
124
+ .filter(isRecord)
125
+ .map((senderWindow) => ({
126
+ senderId: stringValue(senderWindow.senderId),
127
+ timeZone: stringValue(senderWindow.timeZone),
128
+ selectedDates: arrayValue(senderWindow.selectedDates)
129
+ .map((entry) => stringValue(entry))
130
+ .filter((entry) => Boolean(entry)),
131
+ }));
132
+ }
133
+ export function dateWindowFromPlan(plan, selector) {
134
+ const packet = isRecord(plan.packet) ? plan.packet : {};
135
+ const request = isRecord(packet.request) ? packet.request : {};
136
+ const targetDate = stringValue(request.targetDate) ?? selector.targetDate ?? null;
137
+ const untilDate = stringValue(request.untilDate) ?? selector.untilDate ?? null;
138
+ const horizonSendDays = numberValue(request.horizonSendDays) ?? selector.horizonSendDays ?? null;
139
+ const source = targetDate
140
+ ? "target_date"
141
+ : untilDate
142
+ ? "until_date"
143
+ : horizonSendDays !== null
144
+ ? "horizon_send_days"
145
+ : selector.source;
146
+ const selectedDates = selectedDatesFromPlan(plan);
147
+ return {
148
+ version: 1,
149
+ source,
150
+ targetDate: source === "target_date" ? targetDate : null,
151
+ untilDate: source === "until_date" ? untilDate : null,
152
+ horizonSendDays: source === "horizon_send_days" ? horizonSendDays : null,
153
+ selectedDates: selectedDates.length > 0
154
+ ? selectedDates
155
+ : targetDate
156
+ ? [targetDate]
157
+ : [],
158
+ senderWindows: senderWindowsFromPlan(plan),
159
+ };
160
+ }
161
+ export function dateWindowFromRunState(runState) {
162
+ const state = isRecord(runState) ? runState : {};
163
+ const raw = isRecord(state.dateWindow) ? state.dateWindow : null;
164
+ if (!raw || raw.version !== 1)
165
+ return null;
166
+ const source = raw.source === "target_date" ||
167
+ raw.source === "until_date" ||
168
+ raw.source === "horizon_send_days" ||
169
+ raw.source === "default_scheduler_forward"
170
+ ? raw.source
171
+ : null;
172
+ if (!source)
173
+ return null;
174
+ return {
175
+ version: 1,
176
+ source,
177
+ targetDate: source === "target_date" ? stringValue(raw.targetDate) : null,
178
+ untilDate: source === "until_date" ? stringValue(raw.untilDate) : null,
179
+ horizonSendDays: source === "horizon_send_days"
180
+ ? numberValue(raw.horizonSendDays)
181
+ : null,
182
+ selectedDates: arrayValue(raw.selectedDates)
183
+ .map((entry) => stringValue(entry))
184
+ .filter((entry) => Boolean(entry)),
185
+ };
186
+ }
187
+ export function selectorFromDateWindow(window) {
188
+ return {
189
+ source: window.source,
190
+ targetDate: window.targetDate,
191
+ untilDate: window.untilDate,
192
+ horizonSendDays: window.horizonSendDays,
193
+ };
194
+ }
195
+ export function dateSelectorMatchesWindow(selector, window) {
196
+ return (selector.source === window.source &&
197
+ selector.targetDate === window.targetDate &&
198
+ selector.untilDate === window.untilDate &&
199
+ selector.horizonSendDays === window.horizonSendDays);
200
+ }
201
+ export function schedulerSweepTargetDates(window) {
202
+ if (window.source === "target_date" && window.targetDate) {
203
+ return [window.targetDate];
204
+ }
205
+ if (window.source === "until_date" ||
206
+ window.source === "horizon_send_days") {
207
+ return window.selectedDates;
208
+ }
209
+ return [];
210
+ }
@@ -1027,23 +1027,6 @@ async function gatePlan(input, deps, ctx) {
1027
1027
  fallbackSummary: line.fallbackSummary,
1028
1028
  }));
1029
1029
  const fingerprint = fingerprintFromPlan(plan);
1030
- const approvedTargetShapeRevision = stringValue(input.approval?.targetShapeRevision);
1031
- if (approvedTargetShapeRevision &&
1032
- approvedTargetShapeRevision !== fingerprint.targetShapeRevision) {
1033
- return {
1034
- status: "blocked",
1035
- blocker: "scope_drift",
1036
- runId: ctx.runId,
1037
- fence: ctx.fence,
1038
- gate: ctx.gate,
1039
- guidance: "The canonical refill target shape changed after approval; render a new packet before another primitive.",
1040
- report: {
1041
- approvedTargetShapeRevision,
1042
- freshTargetShapeRevision: fingerprint.targetShapeRevision,
1043
- },
1044
- journalPath: ctx.journalPath,
1045
- };
1046
- }
1047
1030
  const persistedCircuit = recordValue(runStateProgress(ctx).prepCircuit);
1048
1031
  if (stringValue(action.type) === "prepare_messages" &&
1049
1032
  openCircuitWaits(persistedCircuit, deps.now?.() ?? new Date())) {
@@ -0,0 +1,28 @@
1
+ type RefillSendsEvergreenInput = {
2
+ workspaceId?: string;
3
+ };
4
+ export declare const refillSendsEvergreenToolDefinitions: {
5
+ name: string;
6
+ description: string;
7
+ inputSchema: {
8
+ type: string;
9
+ properties: {
10
+ workspaceId: {
11
+ type: string;
12
+ description: string;
13
+ };
14
+ };
15
+ required: string[];
16
+ additionalProperties: boolean;
17
+ };
18
+ }[];
19
+ export declare function refillSendsEvergreenCommand(input: RefillSendsEvergreenInput): {
20
+ readOnly: boolean;
21
+ workspaceId: string | null;
22
+ firstOperationalSteps: string[];
23
+ approvalContract: string;
24
+ forbiddenActions: string[];
25
+ fillWindow: string;
26
+ hostExamples: string[];
27
+ };
28
+ export {};
@@ -0,0 +1,47 @@
1
+ export const refillSendsEvergreenToolDefinitions = [
2
+ {
3
+ name: "refill_sends_evergreen",
4
+ description: "Read-only Phase 85 evergreen refill command contract. It performs no mutations and only tells the operator to call get_evergreen_refill_plan for a dry-run packet and journal.",
5
+ inputSchema: {
6
+ type: "object",
7
+ properties: {
8
+ workspaceId: {
9
+ type: "string",
10
+ description: "Explicit request-scoped workspace id.",
11
+ },
12
+ },
13
+ required: ["workspaceId"],
14
+ additionalProperties: false,
15
+ },
16
+ },
17
+ ];
18
+ export function refillSendsEvergreenCommand(input) {
19
+ return {
20
+ readOnly: true,
21
+ workspaceId: input.workspaceId ?? null,
22
+ firstOperationalSteps: [
23
+ "Call get_evergreen_refill_plan with the explicit workspaceId.",
24
+ "Read the returned packet, globalActionQueue, per-sender plans, and itinerary before taking any action.",
25
+ "Review the dry-run journal file path returned by get_evergreen_refill_plan.",
26
+ "Phase 85 is PLAN-ONLY; execution arrives in Phase 86.",
27
+ ],
28
+ approvalContract: "Nothing is approved or executable in Phase 85. The evergreen command is read-only; Phase 86 introduces execution approval.",
29
+ forbiddenActions: [
30
+ "Do not schedule sends.",
31
+ "Do not send messages.",
32
+ "Do not approve messages.",
33
+ "Do not prepare messages.",
34
+ "Do not start or launch campaigns.",
35
+ "Do not create campaigns.",
36
+ "Do not switch providers or source families.",
37
+ "Do not lower paid InMail thresholds.",
38
+ "Do not refresh paid InMail credits.",
39
+ "Do not write scheduler fields.",
40
+ ],
41
+ fillWindow: "Use only the target window and caps returned by get_evergreen_refill_plan.",
42
+ hostExamples: [
43
+ "refill_sends_evergreen({ workspaceId })",
44
+ "get_evergreen_refill_plan({ workspaceId })",
45
+ ],
46
+ };
47
+ }
@@ -167,17 +167,6 @@ export declare function prepareRefillSendsV2Approval(input: RefillV2ApprovalPrep
167
167
  response?: undefined;
168
168
  }>;
169
169
  export declare function refillSendsV2Command(input: RefillSendsV2Input): Promise<{
170
- status: "blocked";
171
- blocker: "approval_expired" | "approval_fingerprint_mismatch";
172
- guidance: string;
173
- report: {
174
- fresh?: {} | null | undefined;
175
- changed: string[];
176
- };
177
- readOnly: boolean;
178
- forbiddenActions: string[];
179
- boundedAuthority: string;
180
- } | {
181
170
  readOnly: boolean;
182
171
  mode: string;
183
172
  forbiddenActions: string[];
@@ -325,11 +325,7 @@ function validateApprovalEcho(envelope, echo, now = new Date()) {
325
325
  ];
326
326
  const changed = fields.filter((field) => echo[field] !== envelope.approval[field]);
327
327
  if (Date.parse(envelope.approval.approvalExpiresAt) <= now.getTime()) {
328
- return {
329
- ok: false,
330
- blocker: "approval_expired",
331
- changed,
332
- };
328
+ return { ok: false, blocker: "approval_expired", changed };
333
329
  }
334
330
  return changed.length === 0
335
331
  ? { ok: true }
@@ -339,85 +335,6 @@ function validateApprovalEcho(envelope, echo, now = new Date()) {
339
335
  changed,
340
336
  };
341
337
  }
342
- function blockedApprovalResult(params) {
343
- return {
344
- status: "blocked",
345
- blocker: params.blocker,
346
- guidance: "The durable refill approval no longer matches its persisted scope; render and approve a new packet before mutation.",
347
- report: {
348
- changed: params.changed,
349
- ...(params.fresh === undefined ? {} : { fresh: params.fresh }),
350
- },
351
- readOnly: false,
352
- forbiddenActions: FORBIDDEN_ACTIONS,
353
- boundedAuthority: BOUNDED_AUTHORITY,
354
- };
355
- }
356
- function storedApprovalFromStatus(value) {
357
- const status = record(value) ?? {};
358
- const config = record(status.config);
359
- const scope = record(config?.scope);
360
- const approval = record(config?.approval);
361
- const scopeHash = text(config?.scopeHash);
362
- if (!config || !scope || !approval || !scopeHash)
363
- return null;
364
- return {
365
- config,
366
- scope,
367
- scopeHash,
368
- approval,
369
- hasDispatched: status.hasDispatched === true,
370
- };
371
- }
372
- function validateStoredApprovalEcho(params) {
373
- const fields = [
374
- "scopeHash",
375
- "targetShapeRevision",
376
- "actionFingerprint",
377
- "expectedTargetsHash",
378
- "approvalExpiresAt",
379
- "approvalFingerprint",
380
- ];
381
- const changed = fields.filter((field) => text(params.approval[field]) !== params.echo[field]);
382
- const expiresAt = text(params.approval.approvalExpiresAt);
383
- if (!params.allowExpired &&
384
- (!expiresAt ||
385
- Date.parse(expiresAt) <= (params.now ?? new Date()).getTime())) {
386
- return {
387
- ok: false,
388
- blocker: "approval_expired",
389
- changed,
390
- };
391
- }
392
- return changed.length === 0
393
- ? { ok: true }
394
- : {
395
- ok: false,
396
- blocker: "approval_fingerprint_mismatch",
397
- changed,
398
- };
399
- }
400
- function executionScopeFromStored(scope, fallback) {
401
- const dateSelector = record(scope.dateSelector) ?? {};
402
- const kind = text(dateSelector.kind);
403
- const senderIds = list(scope.senderIds)
404
- .map((value) => text(value))
405
- .filter((value) => value != null);
406
- const approvalMode = scope.approvalMode === "mark_ready" ? "mark_ready" : "approve";
407
- return {
408
- intent: text(scope.intent) ?? fallback.intent,
409
- senderIds,
410
- approvalMode,
411
- ...(kind === "target_date" && text(dateSelector.targetDate)
412
- ? { targetDate: text(dateSelector.targetDate) }
413
- : kind === "until_date" && text(dateSelector.untilDate)
414
- ? { untilDate: text(dateSelector.untilDate) }
415
- : kind === "horizon_send_days" &&
416
- typeof dateSelector.horizonSendDays === "number"
417
- ? { horizonSendDays: dateSelector.horizonSendDays }
418
- : {}),
419
- };
420
- }
421
338
  async function maybeAddLostFenceGuidance(result, input) {
422
339
  if (result.status !== "blocked" ||
423
340
  result.blocker !== "lease_lost" ||
@@ -448,53 +365,7 @@ export async function refillSendsV2Command(input) {
448
365
  let resolvedScope = input.scope;
449
366
  let resolvedScopeHash = input.scopeHash;
450
367
  let resolvedApproval = input.approval;
451
- if (input.runId && input.approvalEcho) {
452
- const status = await refillRunStatus({ workspaceId, runId: input.runId });
453
- const stored = storedApprovalFromStatus(status);
454
- if (!stored) {
455
- return {
456
- status: "blocked",
457
- blocker: "approval_run_unavailable",
458
- guidance: "The durable refill run no longer exposes a valid persisted approval packet.",
459
- report: { status },
460
- readOnly: false,
461
- forbiddenActions: FORBIDDEN_ACTIONS,
462
- boundedAuthority: BOUNDED_AUTHORITY,
463
- };
464
- }
465
- const validation = validateStoredApprovalEcho({
466
- approval: stored.approval,
467
- echo: input.approvalEcho,
468
- allowExpired: stored.hasDispatched,
469
- });
470
- if (!validation.ok) {
471
- return blockedApprovalResult({
472
- blocker: validation.blocker,
473
- changed: validation.changed,
474
- fresh: stored.approval,
475
- });
476
- }
477
- const freshTargetShapeRevision = input.targetPlan
478
- ? (text(input.targetPlan.targetShapeRevision) ??
479
- text(record(input.targetPlan.target)?.targetShapeRevision))
480
- : null;
481
- const storedTargetShapeRevision = text(stored.approval.targetShapeRevision);
482
- if (freshTargetShapeRevision &&
483
- freshTargetShapeRevision !== storedTargetShapeRevision) {
484
- return blockedApprovalResult({
485
- blocker: "approval_fingerprint_mismatch",
486
- changed: ["targetShapeRevision"],
487
- fresh: {
488
- storedTargetShapeRevision,
489
- freshTargetShapeRevision,
490
- },
491
- });
492
- }
493
- resolvedScope = stored.scope;
494
- resolvedScopeHash = stored.scopeHash;
495
- resolvedApproval = stored.approval;
496
- }
497
- else if (input.targetPlan && input.approvalEcho) {
368
+ if (input.targetPlan && input.approvalEcho) {
498
369
  const envelope = buildApprovalEnvelope({
499
370
  workspaceId,
500
371
  intent: input.intent,
@@ -508,11 +379,15 @@ export async function refillSendsV2Command(input) {
508
379
  });
509
380
  const validation = validateApprovalEcho(envelope, input.approvalEcho);
510
381
  if (!validation.ok) {
511
- return blockedApprovalResult({
382
+ return {
383
+ status: "blocked",
512
384
  blocker: validation.blocker,
513
- changed: validation.changed,
514
- fresh: envelope.approval,
515
- });
385
+ guidance: "The durable refill approval no longer matches fresh scope; render and approve a new packet before mutation.",
386
+ report: { changed: validation.changed, fresh: envelope.approval },
387
+ readOnly: false,
388
+ forbiddenActions: FORBIDDEN_ACTIONS,
389
+ boundedAuthority: BOUNDED_AUTHORITY,
390
+ };
516
391
  }
517
392
  resolvedScope = envelope.scope;
518
393
  resolvedScopeHash = envelope.scopeHash;
@@ -534,18 +409,13 @@ export async function refillSendsV2Command(input) {
534
409
  boundedAuthority: BOUNDED_AUTHORITY,
535
410
  };
536
411
  }
537
- const executionScope = resolvedScope
538
- ? executionScopeFromStored(resolvedScope, input)
539
- : {
540
- intent: input.intent,
541
- senderIds: input.senderIds,
542
- approvalMode: input.approvalMode ?? "approve",
543
- ...date,
544
- };
545
412
  const result = await runRefillV2Loop({
546
413
  workspaceId,
547
- ...executionScope,
414
+ intent: input.intent,
415
+ senderIds: input.senderIds,
416
+ approvalMode: input.approvalMode ?? "approve",
548
417
  resume: resumeHandle(input),
418
+ ...date,
549
419
  scope: resolvedScope,
550
420
  scopeHash: resolvedScopeHash,
551
421
  approval: resolvedApproval,
@@ -725,23 +725,6 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
725
725
  intent: RefillSendsIntent;
726
726
  } | {
727
727
  yoloExecution: {
728
- selectedAction: Record<string, unknown> | null;
729
- targetPlanReread: boolean;
730
- status: "blocked";
731
- blocker: "approval_expired" | "approval_fingerprint_mismatch";
732
- guidance: string;
733
- report: {
734
- fresh?: {} | null | undefined;
735
- changed: string[];
736
- };
737
- readOnly: boolean;
738
- forbiddenActions: string[];
739
- boundedAuthority: string;
740
- enabled: boolean;
741
- result?: undefined;
742
- refusalReason?: undefined;
743
- postActionFirstAction?: undefined;
744
- } | {
745
728
  selectedAction: Record<string, unknown> | null;
746
729
  targetPlanReread: boolean;
747
730
  readOnly: boolean;
@@ -1,6 +1,6 @@
1
- import { REFILL_CONTRACT_CACHE_VERSION, REFILL_CONTRACT_HASH, REFILL_CONTRACT_VERSION, renderRefillBootstrapGuidance, renderRefillSafetyGuidance, renderRefillTerminalGuidance, } from "../refill-contract.js";
2
1
  import { actionIds, classifyPaidInmailRefreshReceipt, collectPaidInmailRefreshActions, executeOneYoloPrimitive, firstGlobalAction, normalizeStrings, numberValue, recordValue, refreshPaidInmailCreditsWithRetry, stringValue, } from "./refill-executors.js";
3
2
  import { prepareRefillSendsV2Approval, refillSendsV2Command, } from "./refill-sends-v2.js";
3
+ import { REFILL_CONTRACT_CACHE_VERSION, REFILL_CONTRACT_HASH, REFILL_CONTRACT_VERSION, renderRefillBootstrapGuidance, renderRefillSafetyGuidance, renderRefillTerminalGuidance, } from "../refill-contract.js";
4
4
  import { getRefillTargetPlan } from "./refill-target-plan.js";
5
5
  import { createWorkspaceContext, normalizeExplicitWorkspaceId, } from "./workspace-context.js";
6
6
  const REFILL_SEND_ACTION_TYPES = ["send_invite", "send_inmail_closed"];
@@ -563,13 +563,8 @@ export async function executeRefillSendsCommand(input = {}) {
563
563
  }
564
564
  const targetPlanInput = targetPlanInputFor(scopedInput);
565
565
  const targetPlanBeforePaidRefresh = await getRefillTargetPlan(targetPlanInput);
566
- const durableResumeRequested = Boolean(yolo &&
567
- workspaceId &&
568
- scopedInput.runId &&
569
- typeof scopedInput.fence === "number" &&
570
- scopedInput.approvalFingerprint);
571
566
  const approvedPacket = approvedPacketComparison(scopedInput, targetPlanBeforePaidRefresh);
572
- if (!durableResumeRequested && approvedPacket.changed) {
567
+ if (approvedPacket.changed) {
573
568
  return {
574
569
  ...command,
575
570
  ok: false,
@@ -600,8 +595,7 @@ export async function executeRefillSendsCommand(input = {}) {
600
595
  }
601
596
  if (yolo &&
602
597
  workspaceId &&
603
- (durableResumeRequested ||
604
- durableV2PlanEligible(targetPlanBeforePaidRefresh))) {
598
+ durableV2PlanEligible(targetPlanBeforePaidRefresh)) {
605
599
  const base = durableYoloBaseResult({
606
600
  command,
607
601
  targetPlan: targetPlanBeforePaidRefresh,
@@ -142,15 +142,17 @@ export declare function listWorkspaces(): Promise<{
142
142
  workspaces: WorkspaceSummary[];
143
143
  workspaceLock: {
144
144
  enabled: boolean;
145
- workspaceId?: undefined;
146
- hiddenWorkspaceCount?: undefined;
145
+ workspaceId: string;
146
+ hiddenWorkspaceCount: number;
147
+ siblingInventoryFetched: boolean;
147
148
  };
148
149
  } | {
149
150
  workspaces: WorkspaceSummary[];
150
151
  workspaceLock: {
151
152
  enabled: boolean;
152
- workspaceId: string;
153
- hiddenWorkspaceCount: number;
153
+ workspaceId?: undefined;
154
+ hiddenWorkspaceCount?: undefined;
155
+ siblingInventoryFetched?: undefined;
154
156
  };
155
157
  }>;
156
158
  export declare function getActiveWorkspace(): {
@@ -80,19 +80,21 @@ export const workspaceToolDefinitions = [
80
80
  ];
81
81
  export async function listWorkspaces() {
82
82
  const api = getApi();
83
- const { workspaces } = await api.get("/api/v3/workspaces");
84
83
  const lockedWorkspaceId = getLockedWorkspaceId();
85
- if (!lockedWorkspaceId) {
86
- return { workspaces, workspaceLock: { enabled: false } };
84
+ if (lockedWorkspaceId) {
85
+ const { workspace } = await api.get(`/api/v3/workspaces/${encodeURIComponent(lockedWorkspaceId)}`);
86
+ return {
87
+ workspaces: [workspace],
88
+ workspaceLock: {
89
+ enabled: true,
90
+ workspaceId: lockedWorkspaceId,
91
+ hiddenWorkspaceCount: 0,
92
+ siblingInventoryFetched: false,
93
+ },
94
+ };
87
95
  }
88
- return {
89
- workspaces: workspaces.filter((ws) => ws.id === lockedWorkspaceId),
90
- workspaceLock: {
91
- enabled: true,
92
- workspaceId: lockedWorkspaceId,
93
- hiddenWorkspaceCount: workspaces.filter((ws) => ws.id !== lockedWorkspaceId).length,
94
- },
95
- };
96
+ const { workspaces } = await api.get("/api/v3/workspaces");
97
+ return { workspaces, workspaceLock: { enabled: false } };
96
98
  }
97
99
  export function getActiveWorkspace() {
98
100
  const config = getConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.560",
3
+ "version": "0.1.561-hermes031.202607110338",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code, Codex, and Hermes campaign workflows",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,9 @@
1
+ {
2
+ "parallelMode": "wide",
3
+ "agentCount": 6,
4
+ "maxToolCallsPerAgent": 2,
5
+ "senderMaxAgents": 2,
6
+ "senderMaxToolCallsPerAgent": 3,
7
+ "progressMode": true,
8
+ "debugMode": true
9
+ }