@indigoai-us/hq-cli 5.345.190 → 5.345.193
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/CHANGELOG.md +420 -0
- package/assets/bot-workers/setup/worker.yaml +91 -34
- package/dist/command-catalog.generated.d.ts +96 -19
- package/dist/command-catalog.generated.js +124 -21
- package/dist/commands/bot-jobs.d.ts +21 -18
- package/dist/commands/bot-jobs.js +127 -39
- package/dist/commands/bot.d.ts +7 -4
- package/dist/commands/bot.js +289 -140
- package/dist/commands/core-jobs-schedule.js +10 -0
- package/dist/commands/daemon.js +37 -0
- package/dist/commands/files.d.ts +41 -6
- package/dist/commands/files.js +108 -27
- package/dist/commands/pack-start-bot.d.ts +4 -6
- package/dist/commands/pack-start-bot.js +4 -8
- package/dist/commands/signals-run.d.ts +45 -0
- package/dist/commands/signals-run.js +175 -0
- package/dist/commands/signals.d.ts +1 -0
- package/dist/commands/signals.js +3 -0
- package/dist/commands/sources.d.ts +11 -0
- package/dist/commands/sources.js +137 -25
- package/dist/commands/staff/reset-test-account.d.ts +10 -0
- package/dist/commands/staff/reset-test-account.js +18 -2
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +31171 -52512
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/bot/api.d.ts +3 -2
- package/dist/lib/bot/config.d.ts +2 -0
- package/dist/lib/bot/fleet-cron.d.ts +121 -0
- package/dist/lib/bot/fleet-cron.js +319 -0
- package/dist/lib/bot/fleet-local.d.ts +113 -2
- package/dist/lib/bot/fleet-local.js +597 -35
- package/dist/lib/bot/fleet-owner-companies.d.ts +12 -0
- package/dist/lib/bot/fleet-owner-companies.js +30 -0
- package/dist/lib/bot/fleet-watch.d.ts +25 -0
- package/dist/lib/bot/fleet-watch.js +51 -0
- package/dist/lib/bot/index.d.ts +1 -1
- package/dist/lib/bot/index.js +1 -1
- package/dist/lib/bot/job-run.d.ts +5 -4
- package/dist/lib/bot/job-run.js +5 -4
- package/dist/lib/bot/jobs/hot-signal-sync.d.ts +57 -3
- package/dist/lib/bot/jobs/hot-signal-sync.js +163 -4
- package/dist/lib/bot/local-jobs.d.ts +13 -2
- package/dist/lib/bot/local-jobs.js +17 -4
- package/dist/lib/bot/progress.d.ts +14 -0
- package/dist/lib/bot/progress.js +47 -1
- package/dist/lib/bot/run.d.ts +55 -2
- package/dist/lib/bot/run.js +192 -10
- package/dist/lib/bot/setup-tool-offer.d.ts +1 -0
- package/dist/lib/bot/setup-tool-offer.js +16 -0
- package/dist/lib/bot/signals-engine-flag.d.ts +18 -0
- package/dist/lib/bot/signals-engine-flag.js +30 -0
- package/dist/lib/daemon/catalog.d.ts +4 -0
- package/dist/lib/daemon/catalog.js +29 -9
- package/dist/lib/daemon/legacy.d.ts +6 -0
- package/dist/lib/daemon/legacy.js +16 -10
- package/dist/lib/daemon/run.d.ts +1 -0
- package/dist/lib/daemon/run.js +10 -0
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/flag-registry.d.ts +13 -1
- package/dist/lib/flag-registry.js +46 -0
- package/dist/lib/hot-channels/adapters/attio.d.ts +75 -2
- package/dist/lib/hot-channels/adapters/attio.js +367 -29
- package/dist/lib/hot-channels/adapters/gmail.d.ts +14 -0
- package/dist/lib/hot-channels/adapters/gmail.js +59 -2
- package/dist/lib/hot-channels/adapters/linear.d.ts +24 -0
- package/dist/lib/hot-channels/adapters/linear.js +71 -1
- package/dist/lib/hot-channels/adapters/meetings.js +4 -1
- package/dist/lib/hot-channels/adapters/slack.js +7 -3
- package/dist/lib/hot-channels/alert.js +1 -1
- package/dist/lib/hot-channels/contract.d.ts +11 -0
- package/dist/lib/hot-channels/contract.js +1 -0
- package/dist/lib/hot-channels/cursors.js +1 -1
- package/dist/lib/hot-channels/landing.d.ts +6 -2
- package/dist/lib/hot-channels/landing.js +13 -6
- package/dist/lib/hot-channels/ledger.js +2 -0
- package/dist/lib/hot-channels/loop.js +18 -4
- package/dist/lib/hot-channels/registry.js +9 -1
- package/dist/lib/hot-channels/run.d.ts +18 -0
- package/dist/lib/hot-channels/run.js +15 -4
- package/dist/lib/hot-channels/signals-pass.d.ts +1 -0
- package/dist/lib/hot-channels/signals-pass.js +7 -5
- package/dist/lib/hot-channels/sync-lock.js +22 -6
- package/dist/lib/mesh/live/daemon/install.d.ts +22 -0
- package/dist/lib/mesh/live/daemon/install.js +117 -30
- package/dist/lib/signals/adapters-catalog.d.ts +77 -0
- package/dist/lib/signals/adapters-catalog.js +194 -0
- package/dist/lib/signals/engine.d.ts +196 -0
- package/dist/lib/signals/engine.js +495 -0
- package/dist/lib/signals/failure-alert.d.ts +89 -0
- package/dist/lib/signals/failure-alert.js +175 -0
- package/dist/lib/signals/local-date.d.ts +3 -0
- package/dist/lib/signals/local-date.js +6 -0
- package/dist/lib/signals/projection.d.ts +42 -0
- package/dist/lib/signals/projection.js +67 -0
- package/dist/lib/signals/reply.d.ts +112 -0
- package/dist/lib/signals/reply.js +368 -0
- package/dist/lib/signals/run-lock.d.ts +36 -0
- package/dist/lib/signals/run-lock.js +148 -0
- package/dist/lib/signals/run-record.d.ts +24 -0
- package/dist/lib/signals/run-record.js +82 -0
- package/dist/lib/signals/sanitize.d.ts +105 -0
- package/dist/lib/signals/sanitize.js +439 -0
- package/dist/lib/signals/settings.d.ts +10 -0
- package/dist/lib/signals/settings.js +48 -0
- package/dist/lib/signals/steps/adapters.d.ts +14 -0
- package/dist/lib/signals/steps/adapters.js +156 -0
- package/dist/lib/signals/steps/entity-similarity.d.ts +10 -0
- package/dist/lib/signals/steps/entity-similarity.js +47 -0
- package/dist/lib/signals/steps/extract.d.ts +113 -0
- package/dist/lib/signals/steps/extract.js +765 -0
- package/dist/lib/signals/steps/garden.d.ts +24 -0
- package/dist/lib/signals/steps/garden.js +250 -0
- package/dist/lib/signals/steps/types.d.ts +112 -0
- package/dist/lib/signals/steps/types.js +4 -0
- package/dist/lib/signals/steps/upload.d.ts +43 -0
- package/dist/lib/signals/steps/upload.js +324 -0
- package/dist/lib/signals/write-guard.d.ts +63 -0
- package/dist/lib/signals/write-guard.js +287 -0
- package/dist/utils/resident-package-preload.js +16 -0
- package/package.json +9 -9
- package/dist/lib/bot/fleet-default-flag.d.ts +0 -31
- package/dist/lib/bot/fleet-default-flag.js +0 -127
|
@@ -91,6 +91,16 @@ function parseNaturalLanguage(text) {
|
|
|
91
91
|
return [null, "hour interval must be 1..23"];
|
|
92
92
|
return [`0 */${hours} * * *`, `Every ${hours} hours`];
|
|
93
93
|
}
|
|
94
|
+
// "every morning at 6" / "every evening at 7": a bare hour takes the part of
|
|
95
|
+
// day's meridiem (morning = am, afternoon/evening/night = pm).
|
|
96
|
+
match = /^(?:every\s+)?(morning|afternoon|evening|night)\s+(?:at\s+)?(\d{1,2}(?::\d{2})?)$/.exec(normalized);
|
|
97
|
+
if (match) {
|
|
98
|
+
const clock = parseClock(match[2] + (match[1] === "morning" ? "am" : "pm"));
|
|
99
|
+
if (!clock)
|
|
100
|
+
return [null, "could not parse time: " + match[2]];
|
|
101
|
+
const [hour, minute] = clock;
|
|
102
|
+
return [String(minute) + " " + String(hour) + " * * *", "Every day at " + formatClock(hour, minute)];
|
|
103
|
+
}
|
|
94
104
|
match = /^(?:every\s+)?(weekday|weekdays|day|daily)\s+(?:at\s+)?(.+)$/.exec(normalized);
|
|
95
105
|
if (match) {
|
|
96
106
|
const clock = parseClock(match[2]);
|
package/dist/commands/daemon.js
CHANGED
|
@@ -136,6 +136,7 @@ async function loadDefaults(over) {
|
|
|
136
136
|
windowsSid: over.windowsSid ?? readWindowsSid(run),
|
|
137
137
|
windowsUser: over.windowsUser ?? mesh.resolveWindowsUser(env),
|
|
138
138
|
}).state,
|
|
139
|
+
windowsRecordedMeshTask: platform === "win32" && mesh ? () => mesh.recordedWindowsMeshTaskName(dir ?? home, env) : undefined,
|
|
139
140
|
})),
|
|
140
141
|
resolveHqRoot: over.resolveHqRoot ?? ((flag) => resolveDaemonHqRoot(flag, { env, cwd: process.cwd(), home })),
|
|
141
142
|
userHome: over.userHome ?? ((user) => loginHome(user, run)),
|
|
@@ -1549,6 +1550,42 @@ export function registerDaemonCommand(program, over = {}) {
|
|
|
1549
1550
|
.command("self-update")
|
|
1550
1551
|
.description("Update the hq CLI, Claude, Codex and Grok, then restart the daemon onto a new CLI")
|
|
1551
1552
|
.action(wrap((d) => runServiceSelfUpdate(d)));
|
|
1553
|
+
service
|
|
1554
|
+
.command("fleet-bots-update")
|
|
1555
|
+
.description("Move each installed HQ Fleet bot to the current runtime release while it is idle, and restart it")
|
|
1556
|
+
.action(wrap(async (d) => {
|
|
1557
|
+
const [{ runFleetBotsUpdate, listFleetBots }, local, bot, { botsRoot }, { hasPromotionHold }] = await Promise.all([
|
|
1558
|
+
import("../lib/bot/fleet-watch.js"),
|
|
1559
|
+
import("../lib/bot/fleet-local.js"),
|
|
1560
|
+
import("./bot.js"),
|
|
1561
|
+
import("../lib/bot/paths.js"),
|
|
1562
|
+
import("../lib/bot/promotion-hold.js"),
|
|
1563
|
+
]);
|
|
1564
|
+
const alive = (pid) => {
|
|
1565
|
+
try {
|
|
1566
|
+
process.kill(pid, 0);
|
|
1567
|
+
return true;
|
|
1568
|
+
}
|
|
1569
|
+
catch (error) {
|
|
1570
|
+
return error.code === "EPERM";
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
await runFleetBotsUpdate({
|
|
1574
|
+
listBots: () => listFleetBots(botsRoot()),
|
|
1575
|
+
target: () => local.resolveFleetLocalPointerTarget(),
|
|
1576
|
+
installed: (b) => {
|
|
1577
|
+
if (b.config.enabled === false)
|
|
1578
|
+
return false;
|
|
1579
|
+
const pid = local.fleetLocalGatewayPid(b.config.agentUid);
|
|
1580
|
+
return pid !== null && alive(pid);
|
|
1581
|
+
},
|
|
1582
|
+
heldForPromotion: (b) => hasPromotionHold(b.dir),
|
|
1583
|
+
needsAdoption: (b, release) => local.fleetLocalProfileNeedsAdoption(b.config.agentUid, { release }),
|
|
1584
|
+
busy: (b) => local.fleetLocalBusyReason(b.config.agentUid),
|
|
1585
|
+
update: (b) => bot.updateFleetRuntimeBot(b.name, { busy: () => local.fleetLocalBusyReason(b.config.agentUid) }),
|
|
1586
|
+
log: (line) => d.out(line),
|
|
1587
|
+
});
|
|
1588
|
+
}));
|
|
1552
1589
|
service
|
|
1553
1590
|
.command("sync-core-reconcile")
|
|
1554
1591
|
.description("Read each company's new-sync-engine switch and write this machine's engine homes and legacy off-switches")
|
package/dist/commands/files.d.ts
CHANGED
|
@@ -242,14 +242,41 @@ export declare function runFilesRestore(params: {
|
|
|
242
242
|
}, deps?: {
|
|
243
243
|
confirm?: ConfirmFn;
|
|
244
244
|
}): Promise<FilesRestoreResponse | undefined>;
|
|
245
|
-
|
|
245
|
+
/** Grace period hq-pro applies before a scheduled version purge runs. */
|
|
246
|
+
export declare const PURGE_GRACE_DAYS = 7;
|
|
247
|
+
/**
|
|
248
|
+
* Outcome of `hq files purge`. A current hq-pro schedules the purge
|
|
249
|
+
* (`scheduled`); a server from before the 7-day window deletes the version
|
|
250
|
+
* at once (`purged`), and the CLI reports that rather than a schedule.
|
|
251
|
+
*/
|
|
252
|
+
export type FilesPurgeResult = {
|
|
253
|
+
key: string;
|
|
254
|
+
versionId: string;
|
|
255
|
+
status: "scheduled";
|
|
256
|
+
purgeAt: string;
|
|
257
|
+
} | {
|
|
246
258
|
key: string;
|
|
247
|
-
|
|
259
|
+
versionId: string;
|
|
260
|
+
status: "purged";
|
|
261
|
+
};
|
|
262
|
+
export interface FilesPurgeCancelResult {
|
|
263
|
+
key: string;
|
|
264
|
+
versionId: string;
|
|
265
|
+
status: "cancelled";
|
|
248
266
|
}
|
|
267
|
+
/** The exact command that cancels this purge, including the scope flags. */
|
|
268
|
+
export declare function formatPurgeCancelCommand(params: {
|
|
269
|
+
key: string;
|
|
270
|
+
versionId: string;
|
|
271
|
+
personal: boolean;
|
|
272
|
+
companySlug: string | undefined;
|
|
273
|
+
}): string;
|
|
249
274
|
/**
|
|
250
|
-
* feedback_fc711fc3:
|
|
251
|
-
* (hq-pro POST /v1/files/restore, action "purge") enforces
|
|
252
|
-
* refuses the current version and delete markers,
|
|
275
|
+
* feedback_fc711fc3: schedule permanent deletion of one noncurrent version.
|
|
276
|
+
* The server (hq-pro POST /v1/files/restore, action "purge") enforces
|
|
277
|
+
* owner-only access, refuses the current version and delete markers, audits,
|
|
278
|
+
* and schedules the deletion PURGE_GRACE_DAYS out (cancelable). An older
|
|
279
|
+
* server deletes immediately; the CLI reports what the server says it did.
|
|
253
280
|
*/
|
|
254
281
|
export declare function runFilesPurge(params: {
|
|
255
282
|
key: string;
|
|
@@ -259,7 +286,15 @@ export declare function runFilesPurge(params: {
|
|
|
259
286
|
companySlug: string | undefined;
|
|
260
287
|
}, deps?: {
|
|
261
288
|
confirm?: ConfirmFn;
|
|
262
|
-
|
|
289
|
+
now?: () => Date;
|
|
290
|
+
}): Promise<FilesPurgeResult | undefined>;
|
|
291
|
+
/** Cancel a scheduled purge (hq-pro action "cancel-purge"). */
|
|
292
|
+
export declare function runFilesPurgeCancel(params: {
|
|
293
|
+
key: string;
|
|
294
|
+
versionId: string;
|
|
295
|
+
personal: boolean;
|
|
296
|
+
companySlug: string | undefined;
|
|
297
|
+
}): Promise<FilesPurgeCancelResult>;
|
|
263
298
|
export declare function runFilesTrash(params: {
|
|
264
299
|
prefix: string;
|
|
265
300
|
cursor?: string;
|
package/dist/commands/files.js
CHANGED
|
@@ -733,15 +733,25 @@ export function registerFilesCommand(program) {
|
|
|
733
733
|
});
|
|
734
734
|
files
|
|
735
735
|
.command("purge <path>")
|
|
736
|
-
.description("
|
|
736
|
+
.description("Schedule permanent deletion of ONE retained (noncurrent) version of an exact vault key, for example a version that held data which must not live in HQ. The version is deleted 7 days later and can be cancelled until then with --cancel. Owner only; audited. Delete the file first if the version is current. Use --personal for your personal vault.")
|
|
737
737
|
.option("--personal", "Target your own personal vault instead of a company vault (mutually exclusive with --company)")
|
|
738
738
|
.requiredOption("--version-id <id>", "Exact version ID to purge (see `hq files versions`)")
|
|
739
|
+
.option("--cancel", "Cancel a scheduled purge of this version instead of scheduling one")
|
|
739
740
|
.option("-y, --yes", "Skip the confirmation prompt (for scripts)")
|
|
740
741
|
.action(async (path, opts) => {
|
|
741
742
|
try {
|
|
742
743
|
const companySlug = files.opts().company;
|
|
743
744
|
const personal = opts.personal === true;
|
|
744
745
|
assertRecoveryScope(personal, companySlug);
|
|
746
|
+
if (opts.cancel === true) {
|
|
747
|
+
await runFilesPurgeCancel({
|
|
748
|
+
key: path,
|
|
749
|
+
versionId: opts.versionId,
|
|
750
|
+
personal,
|
|
751
|
+
companySlug,
|
|
752
|
+
});
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
745
755
|
await runFilesPurge({
|
|
746
756
|
key: path,
|
|
747
757
|
versionId: opts.versionId,
|
|
@@ -1791,31 +1801,39 @@ export async function runFilesRestore(params, deps = {}) {
|
|
|
1791
1801
|
console.log(chalk.dim("New version: " + data.newVersionId));
|
|
1792
1802
|
return data;
|
|
1793
1803
|
}
|
|
1794
|
-
/**
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1804
|
+
/** Grace period hq-pro applies before a scheduled version purge runs. */
|
|
1805
|
+
export const PURGE_GRACE_DAYS = 7;
|
|
1806
|
+
function formatPurgeDate(iso) {
|
|
1807
|
+
const d = new Date(iso);
|
|
1808
|
+
if (Number.isNaN(d.getTime()))
|
|
1809
|
+
return iso;
|
|
1810
|
+
return d.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, " UTC");
|
|
1811
|
+
}
|
|
1812
|
+
function shellQuote(value) {
|
|
1813
|
+
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
1814
|
+
}
|
|
1815
|
+
/** The exact command that cancels this purge, including the scope flags. */
|
|
1816
|
+
export function formatPurgeCancelCommand(params) {
|
|
1817
|
+
const scope = params.personal
|
|
1818
|
+
? ""
|
|
1819
|
+
: params.companySlug
|
|
1820
|
+
? " --company " + shellQuote(params.companySlug)
|
|
1821
|
+
: "";
|
|
1822
|
+
return ("hq files" + scope + " purge --cancel " + shellQuote(params.key) +
|
|
1823
|
+
" --version-id " + shellQuote(params.versionId) +
|
|
1824
|
+
(params.personal ? " --personal" : ""));
|
|
1825
|
+
}
|
|
1826
|
+
function assertPurgeVersionId(versionId) {
|
|
1827
|
+
if (typeof versionId !== "string" || versionId.trim() === "") {
|
|
1802
1828
|
throw new Error("--version-id is required and must not be empty.");
|
|
1803
1829
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
const ok = await confirm("Permanently delete version '" + params.versionId + "' of '" + params.key + "'" +
|
|
1807
|
-
(params.personal ? " in your personal vault" : "") +
|
|
1808
|
-
"? This cannot be undone.");
|
|
1809
|
-
if (!ok) {
|
|
1810
|
-
console.log(chalk.dim("Aborted — nothing was purged."));
|
|
1811
|
-
return undefined;
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1830
|
+
}
|
|
1831
|
+
async function postPurgeAction(params, action) {
|
|
1814
1832
|
const scope = await resolveRecoveryScope(params);
|
|
1815
1833
|
const body = scope.personal
|
|
1816
1834
|
? { personal: true, key: params.key }
|
|
1817
1835
|
: { company: scope.companyUid, key: params.key };
|
|
1818
|
-
body.action =
|
|
1836
|
+
body.action = action;
|
|
1819
1837
|
body.purgeVersionId = params.versionId;
|
|
1820
1838
|
// Tripwire: a server without purge support rejects `versionId: null` with
|
|
1821
1839
|
// 400 instead of ignoring `action` and restoring (re-publishing) the version.
|
|
@@ -1829,16 +1847,79 @@ export async function runFilesPurge(params, deps = {}) {
|
|
|
1829
1847
|
if (!res.ok) {
|
|
1830
1848
|
const errBody = (await res.json().catch(() => ({})));
|
|
1831
1849
|
const err = new FilesRecoveryHttpError(res.status, errBody.message ?? errBody.error ?? res.statusText, errBody.code);
|
|
1850
|
+
if (action === "cancel-purge" && res.status === 400) {
|
|
1851
|
+
throw new Error("The server rejected the cancellation: " + err.message + ". If the server predates the 7-day purge window it cannot cancel. Check `hq files versions` to see whether the version still exists.");
|
|
1852
|
+
}
|
|
1832
1853
|
throw new Error(formatFilesRecoveryError(err, params.key));
|
|
1833
1854
|
}
|
|
1834
|
-
const
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1855
|
+
const parsed = await res.json().catch(() => ({}));
|
|
1856
|
+
return parsed !== null && typeof parsed === "object" ? parsed : {};
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
* feedback_fc711fc3: schedule permanent deletion of one noncurrent version.
|
|
1860
|
+
* The server (hq-pro POST /v1/files/restore, action "purge") enforces
|
|
1861
|
+
* owner-only access, refuses the current version and delete markers, audits,
|
|
1862
|
+
* and schedules the deletion PURGE_GRACE_DAYS out (cancelable). An older
|
|
1863
|
+
* server deletes immediately; the CLI reports what the server says it did.
|
|
1864
|
+
*/
|
|
1865
|
+
export async function runFilesPurge(params, deps = {}) {
|
|
1866
|
+
assertExactRecoveryKey(params.key);
|
|
1867
|
+
assertPurgeVersionId(params.versionId);
|
|
1868
|
+
const confirm = deps.confirm ?? realConfirm;
|
|
1869
|
+
if (!params.yes) {
|
|
1870
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
1871
|
+
const expected = new Date(now.getTime() + PURGE_GRACE_DAYS * 24 * 60 * 60 * 1000);
|
|
1872
|
+
const ok = await confirm("Version '" + params.versionId + "' of '" + params.key + "'" +
|
|
1873
|
+
(params.personal ? " in your personal vault" : "") +
|
|
1874
|
+
" will be permanently deleted on " + formatPurgeDate(expected.toISOString()) +
|
|
1875
|
+
" and can be cancelled until then with `hq files purge --cancel`." +
|
|
1876
|
+
" (A server without the 7-day window deletes it immediately.) Continue?");
|
|
1877
|
+
if (!ok) {
|
|
1878
|
+
console.log(chalk.dim("Aborted — nothing was purged."));
|
|
1879
|
+
return undefined;
|
|
1880
|
+
}
|
|
1839
1881
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1882
|
+
const data = await postPurgeAction(params, "purge");
|
|
1883
|
+
const key = typeof data.key === "string" ? data.key : params.key;
|
|
1884
|
+
const saysScheduled = data.status === "scheduled" || data.scheduled === true;
|
|
1885
|
+
const scheduled = saysScheduled &&
|
|
1886
|
+
typeof data.purgeAt === "string" &&
|
|
1887
|
+
!Number.isNaN(new Date(data.purgeAt).getTime()) &&
|
|
1888
|
+
data.purgeVersionId === params.versionId;
|
|
1889
|
+
if (saysScheduled && !scheduled) {
|
|
1890
|
+
// The server says something is scheduled but the response is incomplete.
|
|
1891
|
+
// Do not report "nothing happened": a deletion may be pending.
|
|
1892
|
+
throw new Error("The server reported a scheduled purge but did not return a valid purge date and version id. A purge of this version may be pending. To cancel it, run: " +
|
|
1893
|
+
formatPurgeCancelCommand(params));
|
|
1894
|
+
}
|
|
1895
|
+
if (scheduled) {
|
|
1896
|
+
const purgeAt = data.purgeAt;
|
|
1897
|
+
console.log(chalk.green("Version '" + params.versionId + "' of '" + key + "' will be permanently deleted on " +
|
|
1898
|
+
formatPurgeDate(purgeAt) + ". It can be cancelled until then:"));
|
|
1899
|
+
console.log(chalk.dim(" " + formatPurgeCancelCommand(params)));
|
|
1900
|
+
return { key, versionId: params.versionId, status: "scheduled", purgeAt };
|
|
1901
|
+
}
|
|
1902
|
+
// Older server: it purged at once and echoes purgedVersionId. Say so plainly.
|
|
1903
|
+
if (data.purgedVersionId === params.versionId) {
|
|
1904
|
+
console.log(chalk.yellow("The server deleted version '" + params.versionId + "' of '" + key +
|
|
1905
|
+
"' immediately (it does not support the 7-day purge window yet). This cannot be cancelled."));
|
|
1906
|
+
return { key, versionId: params.versionId, status: "purged" };
|
|
1907
|
+
}
|
|
1908
|
+
throw new Error("The server did not confirm the purge (it may not support purge yet). Check `hq files versions` before retrying.");
|
|
1909
|
+
}
|
|
1910
|
+
/** Cancel a scheduled purge (hq-pro action "cancel-purge"). */
|
|
1911
|
+
export async function runFilesPurgeCancel(params) {
|
|
1912
|
+
assertExactRecoveryKey(params.key);
|
|
1913
|
+
assertPurgeVersionId(params.versionId);
|
|
1914
|
+
const data = await postPurgeAction(params, "cancel-purge");
|
|
1915
|
+
const key = typeof data.key === "string" ? data.key : params.key;
|
|
1916
|
+
const confirmed = (data.status === "cancelled" || data.cancelled === true) &&
|
|
1917
|
+
data.purgeVersionId === params.versionId;
|
|
1918
|
+
if (!confirmed) {
|
|
1919
|
+
throw new Error("The server did not confirm the cancellation (it may not support the 7-day purge window yet). Check `hq files versions` to see whether the version still exists.");
|
|
1920
|
+
}
|
|
1921
|
+
console.log(chalk.green("Cancelled the scheduled purge of version '" + params.versionId + "' of '" + key + "'."));
|
|
1922
|
+
return { key, versionId: params.versionId, status: "cancelled" };
|
|
1842
1923
|
}
|
|
1843
1924
|
export async function runFilesTrash(params) {
|
|
1844
1925
|
if (params.prefix.includes("*")) {
|
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
import type { InstallPackResult } from "./pack-install.js";
|
|
8
8
|
import { type StartPackBotDeps, type StartPackBotResult } from "../lib/packages/start-bot.js";
|
|
9
9
|
/**
|
|
10
|
-
* The model
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* The person can still change either with `hq bot set`.
|
|
10
|
+
* The model a pack's setup bot runs on. Left unset, Claude Code used the
|
|
11
|
+
* account's default model (Claude Fable 5.1 in a 2026-10-12 walkthrough), and
|
|
12
|
+
* one setup turn took nine minutes. Pack setup is guided reading and writing:
|
|
13
|
+
* Opus 5.5 does it well and faster.
|
|
15
14
|
*/
|
|
16
15
|
export declare const PACK_BOT_MODEL = "claude-opus-5-5";
|
|
17
|
-
export declare const PACK_BOT_EFFORT = "medium";
|
|
18
16
|
export declare function defaultStartPackBotDeps(): StartPackBotDeps;
|
|
19
17
|
/**
|
|
20
18
|
* Start the pack's setup bot after a successful install. Never throws: a bot
|
|
@@ -32,14 +32,12 @@ async function dmOwner(name, body) {
|
|
|
32
32
|
await new BotApi({ token: async () => token }).sendDm({ toPersonUid: owner, body });
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* The model
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* The person can still change either with `hq bot set`.
|
|
35
|
+
* The model a pack's setup bot runs on. Left unset, Claude Code used the
|
|
36
|
+
* account's default model (Claude Fable 5.1 in a 2026-10-12 walkthrough), and
|
|
37
|
+
* one setup turn took nine minutes. Pack setup is guided reading and writing:
|
|
38
|
+
* Opus 5.5 does it well and faster.
|
|
40
39
|
*/
|
|
41
40
|
export const PACK_BOT_MODEL = "claude-opus-5-5";
|
|
42
|
-
export const PACK_BOT_EFFORT = "medium";
|
|
43
41
|
export function defaultStartPackBotDeps() {
|
|
44
42
|
return {
|
|
45
43
|
botExists,
|
|
@@ -48,9 +46,7 @@ export function defaultStartPackBotDeps() {
|
|
|
48
46
|
displayName: opts.displayName,
|
|
49
47
|
intro: opts.intro,
|
|
50
48
|
kickoff: opts.kickoff,
|
|
51
|
-
lean: true,
|
|
52
49
|
model: PACK_BOT_MODEL,
|
|
53
|
-
effort: PACK_BOT_EFFORT,
|
|
54
50
|
}),
|
|
55
51
|
restartBot: (name) => runBotRestart(name, { output: "text" }),
|
|
56
52
|
sendIntro: (name) => runBotIntro(name),
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `hq signals run` — local signals engine (Hot-Signal Sync US-002).
|
|
3
|
+
*
|
|
4
|
+
* Loops over every company in scope whose signals_capture or
|
|
5
|
+
* ontology_capture preference is on and runs the fixed step order
|
|
6
|
+
* garden -> adapters -> extract -> garden -> upload, writing a run record
|
|
7
|
+
* under workspace/signals/runs/{date}/. The engine lives in
|
|
8
|
+
* src/lib/signals/engine.ts and is callable as runSignals().
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
import { type RunSignalsResult, type SignalsStepChoice, type SignalsTrigger } from "../lib/signals/engine.js";
|
|
12
|
+
import type { SignalsRunAlertSenders } from "../lib/signals/failure-alert.js";
|
|
13
|
+
interface RunCliOptions {
|
|
14
|
+
company?: string;
|
|
15
|
+
dryRun?: boolean;
|
|
16
|
+
step: SignalsStepChoice;
|
|
17
|
+
trigger: SignalsTrigger;
|
|
18
|
+
force?: boolean;
|
|
19
|
+
catchUp?: boolean;
|
|
20
|
+
maxTurns?: number;
|
|
21
|
+
maxBudgetUsd?: number;
|
|
22
|
+
json?: boolean;
|
|
23
|
+
reportFound?: boolean;
|
|
24
|
+
hqRoot: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function formatRunResult(result: RunSignalsResult, dryRun: boolean): string;
|
|
27
|
+
export declare function foundSignalsReply(result: RunSignalsResult, company: string | undefined, timeZone: string): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* The terminal alert sender for `hq signals run` (US-018). The CLI has no
|
|
30
|
+
* owner-DM sender, so the terminal is the primary alert, as in
|
|
31
|
+
* `hq sources sync`. A printed alert does not record the hourly dedupe entry,
|
|
32
|
+
* so it never holds back the bot's owner DM for the same company.
|
|
33
|
+
*/
|
|
34
|
+
export declare function terminalSignalsAlert(write?: (text: string) => void): SignalsRunAlertSenders;
|
|
35
|
+
/**
|
|
36
|
+
* Exit codes (run record contract v2): 0 complete, partial, skipped or the
|
|
37
|
+
* job already ran today; 1 failed; 2 usage or config error; 3 another run
|
|
38
|
+
* holds a company's lock (stdout then carries {"status":"running",...}).
|
|
39
|
+
*/
|
|
40
|
+
export declare function runSignalsCli(options: RunCliOptions, overrides?: {
|
|
41
|
+
signalsAlert?: SignalsRunAlertSenders;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
export declare function registerSignalsRunSubcommand(signals: Command): void;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=signals-run.d.ts.map
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `hq signals run` — local signals engine (Hot-Signal Sync US-002).
|
|
3
|
+
*
|
|
4
|
+
* Loops over every company in scope whose signals_capture or
|
|
5
|
+
* ontology_capture preference is on and runs the fixed step order
|
|
6
|
+
* garden -> adapters -> extract -> garden -> upload, writing a run record
|
|
7
|
+
* under workspace/signals/runs/{date}/. The engine lives in
|
|
8
|
+
* src/lib/signals/engine.ts and is callable as runSignals().
|
|
9
|
+
*/
|
|
10
|
+
import { InvalidArgumentError, Option } from "commander";
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import { DEFAULT_HQ_ROOT } from "../utils/cognito-session.js";
|
|
13
|
+
import { Sentry } from "../sentry.js";
|
|
14
|
+
import { runSignals, signalsExitCode, SignalsUsageError, SIGNALS_STEP_CHOICES, SIGNALS_TRIGGERS, } from "../lib/signals/engine.js";
|
|
15
|
+
import { formatRunReply } from "../lib/signals/reply.js";
|
|
16
|
+
function parsePositiveInt(v) {
|
|
17
|
+
const n = Number(v);
|
|
18
|
+
if (!Number.isInteger(n) || n <= 0)
|
|
19
|
+
throw new InvalidArgumentError("must be a positive integer");
|
|
20
|
+
return n;
|
|
21
|
+
}
|
|
22
|
+
function parseNonNegative(v) {
|
|
23
|
+
const n = Number(v);
|
|
24
|
+
if (!Number.isFinite(n) || n < 0)
|
|
25
|
+
throw new InvalidArgumentError("must be a non-negative number");
|
|
26
|
+
return n;
|
|
27
|
+
}
|
|
28
|
+
function envCatchUp() {
|
|
29
|
+
const v = process.env.HQ_SIGNALS_CATCH_UP;
|
|
30
|
+
return v === "1" || v === "true";
|
|
31
|
+
}
|
|
32
|
+
export function formatRunResult(result, dryRun) {
|
|
33
|
+
const lines = [];
|
|
34
|
+
lines.push(`${dryRun ? "Dry run" : "Signals run"} ${result.date}: ${result.summary.status}`);
|
|
35
|
+
if (result.records.length === 0 && result.locked.length === 0)
|
|
36
|
+
lines.push(" no companies in scope");
|
|
37
|
+
for (const l of result.locked) {
|
|
38
|
+
lines.push(` ${l.company}: running (another ${l.trigger} run started ${l.startedAt}; nothing started)`);
|
|
39
|
+
}
|
|
40
|
+
for (const r of result.records) {
|
|
41
|
+
let head = ` ${r.company}: ${r.status}`;
|
|
42
|
+
if (r.skipReason)
|
|
43
|
+
head += ` (${r.skipReason})`;
|
|
44
|
+
if (r.alreadyRanToday)
|
|
45
|
+
head += " (already ran today)";
|
|
46
|
+
if (r.partialReason)
|
|
47
|
+
head += ` (${r.partialReason})`;
|
|
48
|
+
lines.push(head);
|
|
49
|
+
if (r.failureReason && !r.alreadyRanToday)
|
|
50
|
+
lines.push(` ${r.failureReason}`);
|
|
51
|
+
if (r.nextRetryAt && !r.alreadyRanToday)
|
|
52
|
+
lines.push(` next retry after ${r.nextRetryAt}`);
|
|
53
|
+
for (const s of r.steps) {
|
|
54
|
+
if (dryRun) {
|
|
55
|
+
lines.push(` would run ${s.name}`);
|
|
56
|
+
for (const p of s.plan ?? [])
|
|
57
|
+
lines.push(` ${p}`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const extra = s.skippedReason ? ` ${s.skippedReason}` : s.error ? ` ${s.error}` : "";
|
|
61
|
+
const up = s.uploaded ? ` uploaded=${s.uploaded.count} (${s.uploaded.bytes}B)` : "";
|
|
62
|
+
lines.push(` ${s.name.padEnd(9)} ${s.status} in=${s.itemsIn} out=${s.itemsOut}${up}${extra}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return `${lines.join("\n")}\n`;
|
|
66
|
+
}
|
|
67
|
+
export function foundSignalsReply(result, company, timeZone) {
|
|
68
|
+
const record = result.records.find((r) => !company || r.company === company);
|
|
69
|
+
if (!record || record.alreadyRanToday || (record.status !== "complete" && record.status !== "partial"))
|
|
70
|
+
return null;
|
|
71
|
+
const extract = record.steps.find((s) => s.name === "extract" && s.status !== "skipped");
|
|
72
|
+
if (!extract || extract.itemsOut <= 0)
|
|
73
|
+
return null;
|
|
74
|
+
return formatRunReply(record, result.summary, { timeZone }).text;
|
|
75
|
+
}
|
|
76
|
+
function localTimeZone() {
|
|
77
|
+
try {
|
|
78
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return "UTC";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The terminal alert sender for `hq signals run` (US-018). The CLI has no
|
|
86
|
+
* owner-DM sender, so the terminal is the primary alert, as in
|
|
87
|
+
* `hq sources sync`. A printed alert does not record the hourly dedupe entry,
|
|
88
|
+
* so it never holds back the bot's owner DM for the same company.
|
|
89
|
+
*/
|
|
90
|
+
export function terminalSignalsAlert(write = (text) => void process.stderr.write(text)) {
|
|
91
|
+
return {
|
|
92
|
+
sendOwnerDm: async (text) => {
|
|
93
|
+
write(chalk.red(`${text}\n`));
|
|
94
|
+
},
|
|
95
|
+
log: (message) => write(chalk.yellow(`${message}\n`)),
|
|
96
|
+
// A printed alert is not a delivered owner DM: leave the hourly dedupe to the bot.
|
|
97
|
+
recordsDelivery: false,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Exit codes (run record contract v2): 0 complete, partial, skipped or the
|
|
102
|
+
* job already ran today; 1 failed; 2 usage or config error; 3 another run
|
|
103
|
+
* holds a company's lock (stdout then carries {"status":"running",...}).
|
|
104
|
+
*/
|
|
105
|
+
export async function runSignalsCli(options, overrides = {}) {
|
|
106
|
+
const result = await runSignals({
|
|
107
|
+
hqRoot: options.hqRoot,
|
|
108
|
+
company: options.company,
|
|
109
|
+
dryRun: options.dryRun === true,
|
|
110
|
+
step: options.step,
|
|
111
|
+
trigger: options.trigger,
|
|
112
|
+
force: options.force === true,
|
|
113
|
+
catchUp: options.catchUp === true || envCatchUp(),
|
|
114
|
+
maxTurns: options.maxTurns,
|
|
115
|
+
maxBudgetUsd: options.maxBudgetUsd,
|
|
116
|
+
signalsAlert: overrides.signalsAlert ?? terminalSignalsAlert(),
|
|
117
|
+
});
|
|
118
|
+
const code = signalsExitCode(result);
|
|
119
|
+
if (options.reportFound) {
|
|
120
|
+
const reply = foundSignalsReply(result, options.company, localTimeZone());
|
|
121
|
+
if (reply)
|
|
122
|
+
process.stdout.write(`${reply}\n`);
|
|
123
|
+
if (code !== 0)
|
|
124
|
+
process.exitCode = code;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const onlyLocked = result.records.length === 0 && result.locked.length === 1 ? result.locked[0] : undefined;
|
|
128
|
+
if (onlyLocked) {
|
|
129
|
+
const { status, startedAt, trigger } = onlyLocked;
|
|
130
|
+
process.stdout.write(`${JSON.stringify({ status, startedAt, trigger })}\n`);
|
|
131
|
+
}
|
|
132
|
+
else if (options.json) {
|
|
133
|
+
const payload = options.company && result.records.length === 1 ? result.records[0] : result;
|
|
134
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
process.stdout.write(formatRunResult(result, options.dryRun === true));
|
|
138
|
+
}
|
|
139
|
+
if (code !== 0)
|
|
140
|
+
process.exitCode = code;
|
|
141
|
+
}
|
|
142
|
+
export function registerSignalsRunSubcommand(signals) {
|
|
143
|
+
const run = signals.command("run");
|
|
144
|
+
// Usage errors (bad flag or choice) exit 2, not commander's default 1.
|
|
145
|
+
run.exitOverride((err) => process.exit(err.exitCode === 0 ? 0 : 2));
|
|
146
|
+
run
|
|
147
|
+
.description("Run the local signals engine (garden, adapters, extract, garden, upload) for companies with capture on")
|
|
148
|
+
.option("--company <slug>", "Run one company (default: every company listed in the companies manifest)")
|
|
149
|
+
.option("--dry-run", "Print what would run; run no mutating step and write nothing")
|
|
150
|
+
.addOption(new Option("--step <step>", "Run one step").choices([...SIGNALS_STEP_CHOICES]).default("all"))
|
|
151
|
+
.addOption(new Option("--trigger <trigger>", "What started the run").choices([...SIGNALS_TRIGGERS]).default("manual"))
|
|
152
|
+
.option("--force", "Rerun a job trigger that already ran today")
|
|
153
|
+
.option("--catch-up", "Mark the run as a catch-up run (also HQ_SIGNALS_CATCH_UP=1)")
|
|
154
|
+
.option("--max-turns <n>", "Model turn cap for the extract step (default from core/settings/signals.yaml, else 40)", parsePositiveInt)
|
|
155
|
+
.option("--max-budget-usd <x>", "Spend cap in USD for the extract step (default from core/settings/signals.yaml, else 2.00)", parseNonNegative)
|
|
156
|
+
.option("--json", "Print the run record as JSON")
|
|
157
|
+
.option("--report-found", "Print the owner's run reply only when the run found new signals; print nothing otherwise")
|
|
158
|
+
.option("--hq-root <path>", `HQ root (default: ${DEFAULT_HQ_ROOT})`, DEFAULT_HQ_ROOT)
|
|
159
|
+
.action(async (options) => {
|
|
160
|
+
try {
|
|
161
|
+
await runSignalsCli(options);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
165
|
+
process.stderr.write(chalk.red(`✗ ${message}\n`));
|
|
166
|
+
if (err instanceof SignalsUsageError) {
|
|
167
|
+
process.exitCode = 2;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
Sentry.captureException(err);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=signals-run.js.map
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* hq signals get Fetch one signal by id.
|
|
13
13
|
* hq signals types Print the canonical SIGNAL_TYPES enum.
|
|
14
14
|
* hq signals entities List entities the caller has access to.
|
|
15
|
+
* hq signals run Run the local signals engine (signals-run.ts).
|
|
15
16
|
*
|
|
16
17
|
* Mirrors `hq sources` exactly — same flags, same TTY-aware defaults,
|
|
17
18
|
* same error/Sentry plumbing. Defense-in-depth signal-type validation
|
package/dist/commands/signals.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* hq signals get Fetch one signal by id.
|
|
13
13
|
* hq signals types Print the canonical SIGNAL_TYPES enum.
|
|
14
14
|
* hq signals entities List entities the caller has access to.
|
|
15
|
+
* hq signals run Run the local signals engine (signals-run.ts).
|
|
15
16
|
*
|
|
16
17
|
* Mirrors `hq sources` exactly — same flags, same TTY-aware defaults,
|
|
17
18
|
* same error/Sentry plumbing. Defense-in-depth signal-type validation
|
|
@@ -25,6 +26,7 @@ import chalk from "chalk";
|
|
|
25
26
|
import { SIGNAL_TYPES, assertSignalType, resolveEntity, listAvailableEntities, listSignals, getSignal, VaultClient, } from "@indigoai-us/hq-cloud";
|
|
26
27
|
import { ensureCognitoToken, buildVaultConfig, DEFAULT_HQ_ROOT, } from "../utils/cognito-session.js";
|
|
27
28
|
import { Sentry } from "../sentry.js";
|
|
29
|
+
import { registerSignalsRunSubcommand } from "./signals-run.js";
|
|
28
30
|
// ---------------------------------------------------------------------------
|
|
29
31
|
// Access token resolution — honors HQ_ACCESS_TOKEN for tests + CI smoke
|
|
30
32
|
// ---------------------------------------------------------------------------
|
|
@@ -262,5 +264,6 @@ export function registerSignalsCommand(program) {
|
|
|
262
264
|
.description("List entities (companies/personal) your account has access to")
|
|
263
265
|
.option("--format <fmt>", "Output format: table | json (default: table for TTY, json piped)")
|
|
264
266
|
.action(withErrorHandling(async (options) => runEntities(options)));
|
|
267
|
+
registerSignalsRunSubcommand(signals);
|
|
265
268
|
}
|
|
266
269
|
//# sourceMappingURL=signals.js.map
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
import { Command } from "commander";
|
|
24
24
|
import { type RunLedgerAdapterSummary, type RunLedgerEntry, type RunTrigger, type SignalsGeneratedFn } from "../lib/hot-channels/ledger.js";
|
|
25
25
|
import type { HotChannelRegistry } from "../lib/hot-channels/registry.js";
|
|
26
|
+
import { type AdapterFlagReader } from "../lib/signals/adapters-catalog.js";
|
|
26
27
|
import { type SelectionLoader } from "../lib/hot-channels/selection.js";
|
|
28
|
+
import { type FleetCronOps } from "../lib/bot/fleet-cron.js";
|
|
27
29
|
import { type ScheduleReport } from "../lib/hot-channels/schedule.js";
|
|
28
30
|
import { type OnDemandSyncDeps, type OnDemandSyncReport } from "../lib/hot-channels/run.js";
|
|
29
31
|
type ListFormat = "table" | "json";
|
|
@@ -74,6 +76,13 @@ export interface CompanyHotChannelSyncInput {
|
|
|
74
76
|
hqRoot: string;
|
|
75
77
|
company: string;
|
|
76
78
|
adapter?: string;
|
|
79
|
+
/** Registered adapter ids allowed to run; see OnDemandSyncInput.onlyAdapters. */
|
|
80
|
+
onlyAdapters?: readonly string[];
|
|
81
|
+
/**
|
|
82
|
+
* Company flag reader for the adapter gate. Defaults to the shared hq-flags
|
|
83
|
+
* evaluator for this company with the signed-in session.
|
|
84
|
+
*/
|
|
85
|
+
isFlagOn?: AdapterFlagReader;
|
|
77
86
|
registry?: HotChannelRegistry;
|
|
78
87
|
now?: () => Date;
|
|
79
88
|
/** `scheduled` for the bot's hot-signal-sync job; `on-demand` by default. */
|
|
@@ -131,6 +140,8 @@ export interface ScheduleOverrides {
|
|
|
131
140
|
botsRoot?: string;
|
|
132
141
|
/** Whose ledger to read; defaults to the signed-in person. */
|
|
133
142
|
email?: string;
|
|
143
|
+
/** The HQ Fleet Runtime schedule of one bot; defaults to the bot's own runtime. */
|
|
144
|
+
fleetOps?: (agentUid: string) => FleetCronOps;
|
|
134
145
|
}
|
|
135
146
|
export declare class NoHotSignalSyncJobError extends Error {
|
|
136
147
|
readonly company: string;
|