@indigoai-us/hq-cli 5.345.191 → 5.345.194
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 +431 -0
- package/assets/bot-workers/setup/worker.yaml +91 -34
- package/dist/command-catalog.generated.d.ts +145 -19
- package/dist/command-catalog.generated.js +184 -21
- package/dist/commands/bot-jobs.d.ts +21 -18
- package/dist/commands/bot-jobs.js +127 -39
- package/dist/commands/bot.d.ts +4 -3
- package/dist/commands/bot.js +265 -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 +46 -0
- package/dist/commands/signals-run.js +180 -0
- package/dist/commands/signals.d.ts +1 -0
- package/dist/commands/signals.js +3 -0
- package/dist/commands/sources.d.ts +58 -0
- package/dist/commands/sources.js +294 -26
- package/dist/commands/staff/reset-test-account.d.ts +10 -0
- package/dist/commands/staff/reset-test-account.js +18 -2
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.js +35 -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 +93 -1
- package/dist/lib/bot/fleet-local.js +546 -34
- 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.d.ts +6 -0
- package/dist/lib/hot-channels/loop.js +19 -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 +34 -2
- package/dist/lib/hot-channels/signals-pass.js +149 -38
- package/dist/lib/hot-channels/signals-redo.d.ts +60 -0
- package/dist/lib/hot-channels/signals-redo.js +207 -0
- 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 +202 -0
- package/dist/lib/signals/engine.js +504 -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 +118 -0
- package/dist/lib/signals/steps/extract.js +793 -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 +117 -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/dist/utils/vault-api.d.ts +1 -0
- package/dist/utils/vault-api.js +1 -1
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"hq-cli-daemon-sync-runner","type":"module","version":"6.18.
|
|
1
|
+
{"name":"hq-cli-daemon-sync-runner","type":"module","version":"6.18.108","bundleSha256":"b908c99715d125c651043d1a67e0549d7b05e9d6f7ab42b6963b60789df1f2ba","formatVersion":1}
|
package/dist/lib/bot/api.d.ts
CHANGED
|
@@ -39,8 +39,9 @@ export interface InboxItem {
|
|
|
39
39
|
memberCount?: number;
|
|
40
40
|
senderTrust?: "member";
|
|
41
41
|
/**
|
|
42
|
-
* Scheduled-job run items only (channel === "job").
|
|
43
|
-
*
|
|
42
|
+
* Scheduled-job run items only (channel === "job"). A local bot's own loop
|
|
43
|
+
* builds them from its jobs.json (lib/bot/local-jobs.ts); for a hosted agent
|
|
44
|
+
* the cloud fires the job and writes this durable item. The run carries its own
|
|
44
45
|
* prompt instead of `text` (server: hq-pro-agents jobs/run-record.ts
|
|
45
46
|
* `JobRunInboxItem`).
|
|
46
47
|
*/
|
package/dist/lib/bot/config.d.ts
CHANGED
|
@@ -93,6 +93,8 @@ export interface BotConfig {
|
|
|
93
93
|
engine?: BotEngineMetadata;
|
|
94
94
|
fleetAuthPending?: boolean;
|
|
95
95
|
fleetServiceInstallPending?: boolean;
|
|
96
|
+
/** A newer HQ Fleet Local release is installed for this bot; the gateway restarts once the bot is idle. */
|
|
97
|
+
fleetRestartPending?: boolean;
|
|
96
98
|
/**
|
|
97
99
|
* "personal" (acts as its owner everywhere) or "company" (acts as itself,
|
|
98
100
|
* member of `companies`). Missing on bots created before kinds existed:
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { type BotConfig } from "./config.js";
|
|
2
|
+
import { type FleetLocalControlDeps } from "./fleet-local.js";
|
|
3
|
+
export interface FleetCronSchedule {
|
|
4
|
+
kind?: string;
|
|
5
|
+
expr?: string;
|
|
6
|
+
minutes?: number;
|
|
7
|
+
run_at?: string;
|
|
8
|
+
display?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface FleetCronJob {
|
|
11
|
+
id: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
prompt?: string;
|
|
14
|
+
script?: string | null;
|
|
15
|
+
no_agent?: boolean;
|
|
16
|
+
schedule?: FleetCronSchedule;
|
|
17
|
+
schedule_display?: string;
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
state?: string;
|
|
20
|
+
created_at?: string;
|
|
21
|
+
next_run_at?: string | null;
|
|
22
|
+
last_run_at?: string | null;
|
|
23
|
+
last_status?: string | null;
|
|
24
|
+
repeat?: {
|
|
25
|
+
times?: number | null;
|
|
26
|
+
completed?: number;
|
|
27
|
+
};
|
|
28
|
+
deliver?: string;
|
|
29
|
+
origin?: Record<string, unknown> | null;
|
|
30
|
+
workdir?: string | null;
|
|
31
|
+
fire_claim?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface FleetCronOrigin {
|
|
34
|
+
platform: "hqdm";
|
|
35
|
+
chat_id: string;
|
|
36
|
+
user_id: string;
|
|
37
|
+
chat_name?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface FleetCronCreateInput {
|
|
40
|
+
prompt: string;
|
|
41
|
+
schedule: string;
|
|
42
|
+
origin: FleetCronOrigin;
|
|
43
|
+
name?: string;
|
|
44
|
+
script?: string;
|
|
45
|
+
noAgent?: boolean;
|
|
46
|
+
workdir?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface FleetCronOps {
|
|
49
|
+
list(): FleetCronJob[];
|
|
50
|
+
create(input: FleetCronCreateInput): FleetCronJob;
|
|
51
|
+
remove(id: string): boolean;
|
|
52
|
+
reschedule(id: string, schedule: string): FleetCronJob | null;
|
|
53
|
+
}
|
|
54
|
+
export type FleetCronRunner = (executable: string, args: string[], options: Record<string, unknown>) => Buffer | string;
|
|
55
|
+
export interface FleetCronDeps extends Pick<FleetLocalControlDeps, "fleetHome" | "platform"> {
|
|
56
|
+
run?: FleetCronRunner;
|
|
57
|
+
env?: NodeJS.ProcessEnv;
|
|
58
|
+
}
|
|
59
|
+
export declare const FLEET_CRON_BRIDGE: string;
|
|
60
|
+
export declare function runFleetCronRequest(agentUid: string, request: Record<string, unknown>, deps?: FleetCronDeps): unknown;
|
|
61
|
+
export declare function fleetCronOps(agentUid: string, deps?: FleetCronDeps): FleetCronOps;
|
|
62
|
+
export declare function fleetOwnerOrigin(ownerUid: string, jobs?: readonly FleetCronJob[]): FleetCronOrigin;
|
|
63
|
+
export declare function fleetScheduleFromLegacy(expr: string): string;
|
|
64
|
+
export interface FleetJobsMigrationResult {
|
|
65
|
+
imported: number;
|
|
66
|
+
alreadyPresent: number;
|
|
67
|
+
skipped: string[];
|
|
68
|
+
/** Where the old list went. Null when some jobs could not move: jobs.json then stays. */
|
|
69
|
+
renamedTo: string | null;
|
|
70
|
+
}
|
|
71
|
+
export declare function migrateLegacyJobsToFleet(dir: string, config: Pick<BotConfig, "ownerUid" | "hqRoot">, ops: FleetCronOps, now?: Date): FleetJobsMigrationResult | null;
|
|
72
|
+
export declare const FLEET_HOT_SIGNAL_SYNC_NAME = "hot-signal-sync";
|
|
73
|
+
export declare const FLEET_HOT_SIGNAL_SYNC_SCHEDULE = "30 6 * * *";
|
|
74
|
+
export declare function fleetHotSignalSyncScript(company: string): string;
|
|
75
|
+
export declare function companyOfHotSignalSyncJob(job: FleetCronJob): string | null;
|
|
76
|
+
export declare function renderFleetHotSignalSyncScript(input: {
|
|
77
|
+
nodeBinary: string;
|
|
78
|
+
hqBinary: string;
|
|
79
|
+
company: string;
|
|
80
|
+
hqRoot: string;
|
|
81
|
+
logFile: string;
|
|
82
|
+
/**
|
|
83
|
+
* cli.bot-signals-engine-job. On (the default here): the script runs the
|
|
84
|
+
* signals engine. Off: it runs the plain hot-channel sync (`hq sources sync`),
|
|
85
|
+
* the job these bots ran before the engine.
|
|
86
|
+
*/
|
|
87
|
+
signalsEngine?: boolean;
|
|
88
|
+
}): string;
|
|
89
|
+
export interface EnsureFleetHotSignalSyncInput {
|
|
90
|
+
dir: string;
|
|
91
|
+
config: Pick<BotConfig, "ownerUid" | "hqRoot" | "companySlug" | "kind" | "companies" | "workerId">;
|
|
92
|
+
ops: FleetCronOps;
|
|
93
|
+
profileDir: string;
|
|
94
|
+
activeCompany: string | null;
|
|
95
|
+
ownerCompanies?: readonly string[];
|
|
96
|
+
otherBotDirs: readonly string[];
|
|
97
|
+
nodeBinary: string;
|
|
98
|
+
hqBinary: string;
|
|
99
|
+
/**
|
|
100
|
+
* cli.bot-signals-engine-job (default off). Every company still gets the
|
|
101
|
+
* daily 06:30 hot-signal-sync job; the flag picks what its script runs: the
|
|
102
|
+
* signals engine when true, the plain hot-channel sync when false. The script
|
|
103
|
+
* is rewritten on every call, so flipping the flag takes effect on the next
|
|
104
|
+
* bot start without re-registering the job.
|
|
105
|
+
*/
|
|
106
|
+
signalsJobEnabled: boolean;
|
|
107
|
+
now?: Date;
|
|
108
|
+
}
|
|
109
|
+
export interface FleetHotSignalSyncCompanyResult {
|
|
110
|
+
company: string;
|
|
111
|
+
created: boolean;
|
|
112
|
+
job: FleetCronJob | null;
|
|
113
|
+
heldBy?: string;
|
|
114
|
+
}
|
|
115
|
+
export interface EnsureFleetHotSignalSyncResult {
|
|
116
|
+
companies: FleetHotSignalSyncCompanyResult[];
|
|
117
|
+
removed: string[];
|
|
118
|
+
}
|
|
119
|
+
export declare function fleetHotSignalSyncCompanies(config: EnsureFleetHotSignalSyncInput["config"], activeCompany: string | null, ownerCompanies?: readonly string[]): string[];
|
|
120
|
+
export declare function ensureFleetHotSignalSync(input: EnsureFleetHotSignalSyncInput): EnsureFleetHotSignalSyncResult;
|
|
121
|
+
//# sourceMappingURL=fleet-cron.d.ts.map
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { effectiveBotCompanies, effectiveBotKind } from "./config.js";
|
|
5
|
+
import { fleetLocalRuntimePython, stderrTail } from "./fleet-local.js";
|
|
6
|
+
import { readLocalJobs, withJobsLock, writeLocalJobs } from "./local-jobs.js";
|
|
7
|
+
import { currentHotSignalSyncCompany, forgetHotSignalSyncRegistrationsExcept, hotSignalSyncJobCompany, fleetHotSignalSyncRegistered, markFleetHotSignalSyncRegistered, otherBotWithHotSignalSync, } from "./jobs/hot-signal-sync.js";
|
|
8
|
+
const RESULT_MARKER = "@@HQ_FLEET_CRON@@";
|
|
9
|
+
export const FLEET_CRON_BRIDGE = [
|
|
10
|
+
"import json, os, sys",
|
|
11
|
+
"sys.path.insert(0, sys.argv[1])",
|
|
12
|
+
"request = json.loads(sys.stdin.read())",
|
|
13
|
+
"def emit(value):",
|
|
14
|
+
` sys.stdout.write("\\n${RESULT_MARKER}" + json.dumps(value, default=str) + "\\n")`,
|
|
15
|
+
"try:",
|
|
16
|
+
" from cron import jobs as cron_jobs",
|
|
17
|
+
" with cron_jobs.use_cron_store(os.environ['HQ_FLEET_HOME']):",
|
|
18
|
+
" op = request.get('op')",
|
|
19
|
+
" if op == 'list':",
|
|
20
|
+
" result = cron_jobs.list_jobs(include_disabled=True)",
|
|
21
|
+
" elif op == 'create':",
|
|
22
|
+
" result = cron_jobs.create_job(**request['job'])",
|
|
23
|
+
" elif op == 'remove':",
|
|
24
|
+
" result = cron_jobs.remove_job(request['id'])",
|
|
25
|
+
" elif op == 'reschedule':",
|
|
26
|
+
" result = cron_jobs.update_job(request['id'], {'schedule': request['schedule']})",
|
|
27
|
+
" else:",
|
|
28
|
+
" raise ValueError('unknown operation ' + str(op))",
|
|
29
|
+
" emit({'ok': True, 'result': result})",
|
|
30
|
+
"except Exception as exc:",
|
|
31
|
+
" emit({'ok': False, 'error': str(exc), 'type': type(exc).__name__})",
|
|
32
|
+
].join("\n");
|
|
33
|
+
function expectedError(message) {
|
|
34
|
+
return Object.assign(new Error(message), { expected: true });
|
|
35
|
+
}
|
|
36
|
+
export function runFleetCronRequest(agentUid, request, deps = {}) {
|
|
37
|
+
const runtime = fleetLocalRuntimePython(agentUid, deps);
|
|
38
|
+
const run = deps.run ?? execFileSync;
|
|
39
|
+
let output;
|
|
40
|
+
try {
|
|
41
|
+
output = run(runtime.python, ["-I", "-c", FLEET_CRON_BRIDGE, runtime.source], {
|
|
42
|
+
input: JSON.stringify(request),
|
|
43
|
+
encoding: "utf8",
|
|
44
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
45
|
+
env: { ...(deps.env ?? process.env), HQ_FLEET_HOME: runtime.profileDir, HQ_FLEET_ENABLE_PROJECT_PLUGINS: "0" },
|
|
46
|
+
timeout: 60_000,
|
|
47
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
48
|
+
windowsHide: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const tail = stderrTail(error);
|
|
53
|
+
throw expectedError(`The HQ Fleet Runtime could not open the bot's scheduled jobs.${tail ? `\n${tail}` : ""}`);
|
|
54
|
+
}
|
|
55
|
+
const text = Buffer.isBuffer(output) ? output.toString("utf8") : output;
|
|
56
|
+
const line = text.split(/\r?\n/).reverse().find((entry) => entry.startsWith(RESULT_MARKER));
|
|
57
|
+
if (!line)
|
|
58
|
+
throw expectedError("The HQ Fleet Runtime returned no answer about the bot's scheduled jobs.");
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(line.slice(RESULT_MARKER.length));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw expectedError("The HQ Fleet Runtime returned an unreadable answer about the bot's scheduled jobs.");
|
|
65
|
+
}
|
|
66
|
+
if (parsed.ok !== true) {
|
|
67
|
+
throw expectedError(typeof parsed.error === "string" && parsed.error ? parsed.error : "The HQ Fleet Runtime refused the change.");
|
|
68
|
+
}
|
|
69
|
+
return parsed.result;
|
|
70
|
+
}
|
|
71
|
+
function asJob(value) {
|
|
72
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
73
|
+
return null;
|
|
74
|
+
const record = value;
|
|
75
|
+
return typeof record.id === "string" && record.id ? record : null;
|
|
76
|
+
}
|
|
77
|
+
export function fleetCronOps(agentUid, deps = {}) {
|
|
78
|
+
return {
|
|
79
|
+
list() {
|
|
80
|
+
const result = runFleetCronRequest(agentUid, { op: "list" }, deps);
|
|
81
|
+
return Array.isArray(result) ? result.map(asJob).filter((job) => job !== null) : [];
|
|
82
|
+
},
|
|
83
|
+
create(input) {
|
|
84
|
+
const job = asJob(runFleetCronRequest(agentUid, {
|
|
85
|
+
op: "create",
|
|
86
|
+
job: {
|
|
87
|
+
prompt: input.prompt,
|
|
88
|
+
schedule: input.schedule,
|
|
89
|
+
deliver: "origin",
|
|
90
|
+
origin: input.origin,
|
|
91
|
+
...(input.name ? { name: input.name } : {}),
|
|
92
|
+
...(input.script ? { script: input.script } : {}),
|
|
93
|
+
...(input.noAgent ? { no_agent: true } : {}),
|
|
94
|
+
...(input.workdir ? { workdir: input.workdir } : {}),
|
|
95
|
+
},
|
|
96
|
+
}, deps));
|
|
97
|
+
if (!job)
|
|
98
|
+
throw expectedError("The HQ Fleet Runtime did not return the new job.");
|
|
99
|
+
return job;
|
|
100
|
+
},
|
|
101
|
+
remove(id) {
|
|
102
|
+
return runFleetCronRequest(agentUid, { op: "remove", id }, deps) === true;
|
|
103
|
+
},
|
|
104
|
+
reschedule(id, schedule) {
|
|
105
|
+
return asJob(runFleetCronRequest(agentUid, { op: "reschedule", id, schedule }, deps));
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export function fleetOwnerOrigin(ownerUid, jobs = []) {
|
|
110
|
+
const known = jobs
|
|
111
|
+
.map((job) => job.origin)
|
|
112
|
+
.find((origin) => origin && origin.platform === "hqdm" && origin.chat_id === ownerUid && typeof origin.chat_name === "string" && origin.chat_name);
|
|
113
|
+
return {
|
|
114
|
+
platform: "hqdm",
|
|
115
|
+
chat_id: ownerUid,
|
|
116
|
+
user_id: ownerUid,
|
|
117
|
+
...(known ? { chat_name: known.chat_name } : {}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function throwSchedule(message) {
|
|
121
|
+
throw Object.assign(new Error(message), { expected: true });
|
|
122
|
+
}
|
|
123
|
+
function unshiftDayOfWeekTerm(term) {
|
|
124
|
+
const step = term.match(/^(.+)\/(\d+)$/);
|
|
125
|
+
if (step)
|
|
126
|
+
return `${unshiftDayOfWeekTerm(step[1])}/${step[2]}`;
|
|
127
|
+
if (term === "*")
|
|
128
|
+
return term;
|
|
129
|
+
const range = term.match(/^(\d+)-(\d+)$/);
|
|
130
|
+
if (range)
|
|
131
|
+
return `${Number(range[1]) - 1}-${Number(range[2]) - 1}`;
|
|
132
|
+
if (/^\d+$/.test(term))
|
|
133
|
+
return String(Number(term) - 1);
|
|
134
|
+
return term;
|
|
135
|
+
}
|
|
136
|
+
export function fleetScheduleFromLegacy(expr) {
|
|
137
|
+
const trimmed = expr.trim();
|
|
138
|
+
const rate = trimmed.match(/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i);
|
|
139
|
+
if (rate)
|
|
140
|
+
return `every ${rate[1]}${rate[2].toLowerCase()[0]}`;
|
|
141
|
+
const cron = trimmed.match(/^cron\(\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*\)$/i);
|
|
142
|
+
if (!cron)
|
|
143
|
+
throwSchedule(`"${trimmed}" is not a schedule the HQ Fleet Runtime can run.`);
|
|
144
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek, year] = cron.slice(1);
|
|
145
|
+
if (year !== "*")
|
|
146
|
+
throwSchedule(`"${trimmed}" names a year; the HQ Fleet Runtime runs recurring schedules only.`);
|
|
147
|
+
const dom = dayOfMonth === "?" ? "*" : dayOfMonth;
|
|
148
|
+
const dow = dayOfWeek === "?" ? "*" : dayOfWeek.split(",").map((term) => unshiftDayOfWeekTerm(term.trim())).join(",");
|
|
149
|
+
return `${minute} ${hour} ${dom} ${month} ${dow}`;
|
|
150
|
+
}
|
|
151
|
+
function migratedJobsPath(dir, now) {
|
|
152
|
+
const first = path.join(dir, "jobs.migrated.json");
|
|
153
|
+
if (!fs.existsSync(first))
|
|
154
|
+
return first;
|
|
155
|
+
return path.join(dir, `jobs.migrated-${now.toISOString().replace(/[:.]/g, "-")}.json`);
|
|
156
|
+
}
|
|
157
|
+
export function migrateLegacyJobsToFleet(dir, config, ops, now = new Date()) {
|
|
158
|
+
const file = path.join(dir, "jobs.json");
|
|
159
|
+
if (!fs.existsSync(file))
|
|
160
|
+
return null;
|
|
161
|
+
return withJobsLock(dir, () => {
|
|
162
|
+
const legacy = readLocalJobs(dir).filter((job) => hotSignalSyncJobCompany(job.context) === null);
|
|
163
|
+
if (legacy.length === 0)
|
|
164
|
+
return null;
|
|
165
|
+
const existing = ops.list();
|
|
166
|
+
const origin = fleetOwnerOrigin(config.ownerUid, existing);
|
|
167
|
+
let imported = 0;
|
|
168
|
+
let alreadyPresent = 0;
|
|
169
|
+
const skipped = [];
|
|
170
|
+
const moved = new Set();
|
|
171
|
+
for (const job of legacy) {
|
|
172
|
+
let schedule;
|
|
173
|
+
try {
|
|
174
|
+
schedule = /^(cron|rate)\(/i.test(job.cron.trim()) ? fleetScheduleFromLegacy(job.cron) : job.cron.trim();
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
skipped.push(job.jobId);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const present = existing.some((candidate) => candidate.prompt === job.prompt && candidate.schedule?.expr === schedule);
|
|
181
|
+
if (present) {
|
|
182
|
+
alreadyPresent += 1;
|
|
183
|
+
moved.add(job.jobId);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
existing.push(ops.create({ prompt: job.prompt, schedule, origin, workdir: config.hqRoot }));
|
|
187
|
+
imported += 1;
|
|
188
|
+
moved.add(job.jobId);
|
|
189
|
+
}
|
|
190
|
+
if (skipped.length > 0) {
|
|
191
|
+
// Some jobs could not move. jobs.json stays, with the jobs that could not
|
|
192
|
+
// move left in it; only the jobs now in the Fleet schedule leave it.
|
|
193
|
+
if (moved.size > 0) {
|
|
194
|
+
const all = readLocalJobs(dir);
|
|
195
|
+
writeLocalJobs(dir, all.filter((job) => !moved.has(job.jobId)));
|
|
196
|
+
}
|
|
197
|
+
return { imported, alreadyPresent, skipped, renamedTo: null };
|
|
198
|
+
}
|
|
199
|
+
const renamedTo = migratedJobsPath(dir, now);
|
|
200
|
+
fs.renameSync(file, renamedTo);
|
|
201
|
+
return { imported, alreadyPresent, skipped, renamedTo };
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
export const FLEET_HOT_SIGNAL_SYNC_NAME = "hot-signal-sync";
|
|
205
|
+
export const FLEET_HOT_SIGNAL_SYNC_SCHEDULE = "30 6 * * *";
|
|
206
|
+
export function fleetHotSignalSyncScript(company) {
|
|
207
|
+
return `hot-signal-sync-${company}.py`;
|
|
208
|
+
}
|
|
209
|
+
export function companyOfHotSignalSyncJob(job) {
|
|
210
|
+
if (job.name !== FLEET_HOT_SIGNAL_SYNC_NAME || typeof job.script !== "string")
|
|
211
|
+
return null;
|
|
212
|
+
const match = /^hot-signal-sync-([a-z0-9][a-z0-9_-]*)\.py$/i.exec(path.basename(job.script));
|
|
213
|
+
return match ? match[1] : null;
|
|
214
|
+
}
|
|
215
|
+
export function renderFleetHotSignalSyncScript(input) {
|
|
216
|
+
const args = input.signalsEngine === false
|
|
217
|
+
? ["sources", "sync", "--company", input.company, "--hq-root", input.hqRoot]
|
|
218
|
+
: ["signals", "run", "--trigger", "job", "--company", input.company, "--hq-root", input.hqRoot, "--report-found"];
|
|
219
|
+
// The engine prints only when it finds new signals (--report-found), so its
|
|
220
|
+
// stdout goes to the owner's DM as is. The plain sync prints a report every
|
|
221
|
+
// run, so with the flag off its stdout goes to the log and the owner hears
|
|
222
|
+
// only about a run that failed (for example, nobody signed in).
|
|
223
|
+
const deliver = input.signalsEngine === false
|
|
224
|
+
? [
|
|
225
|
+
" with open(LOG, 'a', encoding='utf-8') as log:",
|
|
226
|
+
" log.write(result.stdout)",
|
|
227
|
+
" if result.returncode != 0:",
|
|
228
|
+
` sys.stdout.write(${JSON.stringify(`The 06:30 hot-channel sync for ${input.company} did not finish. Details are in `)} + LOG + '\\n')`,
|
|
229
|
+
]
|
|
230
|
+
: [" sys.stdout.write(result.stdout)"];
|
|
231
|
+
return [
|
|
232
|
+
"import subprocess, sys",
|
|
233
|
+
`NODE = ${JSON.stringify(input.nodeBinary)}`,
|
|
234
|
+
`HQ = ${JSON.stringify(input.hqBinary)}`,
|
|
235
|
+
`ARGS = ${JSON.stringify(args)}`,
|
|
236
|
+
`LOG = ${JSON.stringify(input.logFile)}`,
|
|
237
|
+
"try:",
|
|
238
|
+
" with open(LOG, 'a', encoding='utf-8') as log:",
|
|
239
|
+
" result = subprocess.run([NODE, HQ, *ARGS], stdout=subprocess.PIPE, stderr=log, text=True)",
|
|
240
|
+
...deliver,
|
|
241
|
+
"except OSError as exc:",
|
|
242
|
+
" with open(LOG, 'a', encoding='utf-8') as log:",
|
|
243
|
+
" log.write('hot-signal-sync could not run hq: ' + str(exc) + '\\n')",
|
|
244
|
+
"",
|
|
245
|
+
].join("\n");
|
|
246
|
+
}
|
|
247
|
+
export function fleetHotSignalSyncCompanies(config, activeCompany, ownerCompanies = []) {
|
|
248
|
+
const single = currentHotSignalSyncCompany(config, activeCompany);
|
|
249
|
+
if (config.companySlug || effectiveBotCompanies(config).length > 0 || effectiveBotKind(config) === "company") {
|
|
250
|
+
return single ? [single] : [];
|
|
251
|
+
}
|
|
252
|
+
const owned = [...new Set(ownerCompanies.map((slug) => slug.trim()).filter((slug) => slug && slug !== "personal"))].sort();
|
|
253
|
+
if (owned.length > 0)
|
|
254
|
+
return owned;
|
|
255
|
+
return single ? [single] : [];
|
|
256
|
+
}
|
|
257
|
+
export function ensureFleetHotSignalSync(input) {
|
|
258
|
+
const companies = fleetHotSignalSyncCompanies(input.config, input.activeCompany, input.ownerCompanies);
|
|
259
|
+
const wanted = new Set(companies);
|
|
260
|
+
const jobs = input.ops.list();
|
|
261
|
+
const removed = [];
|
|
262
|
+
for (const job of jobs) {
|
|
263
|
+
const jobCompany = companyOfHotSignalSyncJob(job);
|
|
264
|
+
if (jobCompany !== null && !wanted.has(jobCompany) && input.ops.remove(job.id))
|
|
265
|
+
removed.push(job.id);
|
|
266
|
+
}
|
|
267
|
+
forgetHotSignalSyncRegistrationsExcept(input.dir, companies);
|
|
268
|
+
const results = [];
|
|
269
|
+
let remaining = jobs.filter((job) => !removed.includes(job.id));
|
|
270
|
+
for (const company of companies) {
|
|
271
|
+
const result = ensureFleetHotSignalSyncFor(input, company, remaining);
|
|
272
|
+
if (result.job && !remaining.some((job) => job.id === result.job.id))
|
|
273
|
+
remaining = [...remaining, result.job];
|
|
274
|
+
results.push(result);
|
|
275
|
+
}
|
|
276
|
+
return { companies: results, removed };
|
|
277
|
+
}
|
|
278
|
+
function ensureFleetHotSignalSyncFor(input, company, jobs) {
|
|
279
|
+
const scriptName = fleetHotSignalSyncScript(company);
|
|
280
|
+
const scriptsDir = path.join(input.profileDir, "scripts");
|
|
281
|
+
fs.mkdirSync(scriptsDir, { recursive: true, mode: 0o700 });
|
|
282
|
+
const logFile = path.join(input.dir, "logs", "hot-signal-sync.log");
|
|
283
|
+
fs.mkdirSync(path.dirname(logFile), { recursive: true, mode: 0o700 });
|
|
284
|
+
const scriptFile = path.join(scriptsDir, scriptName);
|
|
285
|
+
const temporary = `${scriptFile}.${process.pid}.tmp`;
|
|
286
|
+
fs.writeFileSync(temporary, renderFleetHotSignalSyncScript({
|
|
287
|
+
nodeBinary: input.nodeBinary,
|
|
288
|
+
hqBinary: input.hqBinary,
|
|
289
|
+
company,
|
|
290
|
+
hqRoot: input.config.hqRoot,
|
|
291
|
+
logFile,
|
|
292
|
+
signalsEngine: input.signalsJobEnabled === true,
|
|
293
|
+
}), { mode: 0o600 });
|
|
294
|
+
fs.renameSync(temporary, scriptFile);
|
|
295
|
+
const current = jobs.find((job) => companyOfHotSignalSyncJob(job) === company) ?? null;
|
|
296
|
+
if (fleetHotSignalSyncRegistered(input.dir, company))
|
|
297
|
+
return { company, created: false, job: current };
|
|
298
|
+
if (current) {
|
|
299
|
+
markFleetHotSignalSyncRegistered(input.dir, company, input.now);
|
|
300
|
+
return { company, created: false, job: current };
|
|
301
|
+
}
|
|
302
|
+
const heldBy = otherBotWithHotSignalSync(input.dir, company, input.otherBotDirs);
|
|
303
|
+
if (heldBy)
|
|
304
|
+
return { company, created: false, job: null, heldBy };
|
|
305
|
+
const job = input.ops.create({
|
|
306
|
+
name: FLEET_HOT_SIGNAL_SYNC_NAME,
|
|
307
|
+
prompt: input.signalsJobEnabled === true
|
|
308
|
+
? `Run the signals engine for ${company} and post to the owner only when it finds new signals.`
|
|
309
|
+
: `Run the hot-channel sync for ${company}.`,
|
|
310
|
+
schedule: FLEET_HOT_SIGNAL_SYNC_SCHEDULE,
|
|
311
|
+
script: scriptName,
|
|
312
|
+
noAgent: true,
|
|
313
|
+
origin: fleetOwnerOrigin(input.config.ownerUid, [...jobs]),
|
|
314
|
+
workdir: input.config.hqRoot,
|
|
315
|
+
});
|
|
316
|
+
markFleetHotSignalSyncRegistered(input.dir, company, input.now);
|
|
317
|
+
return { company, created: true, job };
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=fleet-cron.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type BotEngineMetadata } from "./config.js";
|
|
2
2
|
import type { BotMachineCreds } from "./creds.js";
|
|
3
3
|
import { type FleetPython } from "./fleet-python.js";
|
|
4
|
+
import { vaultApiFetch } from "../../utils/vault-api.js";
|
|
4
5
|
import type { LocalBotPromotionRuntime } from "./promote.js";
|
|
5
6
|
export interface FleetLocalReleasePin {
|
|
6
7
|
repository: string;
|
|
@@ -80,7 +81,7 @@ export interface FleetLocalProfileInput {
|
|
|
80
81
|
};
|
|
81
82
|
/** Companies the owner's own turns may use; other senders get none of them. */
|
|
82
83
|
ownerCompanies?: string[];
|
|
83
|
-
/**
|
|
84
|
+
/** True turns the runtime's command approval prompts off for every sender (`hq bot create --auto-approve`). */
|
|
84
85
|
autoApprove?: boolean;
|
|
85
86
|
}
|
|
86
87
|
/** The model the HQ Fleet Runtime asks for when a Claude bot names none. */
|
|
@@ -95,10 +96,19 @@ export declare function fleetProviderForRuntime(runtime: string, model?: string)
|
|
|
95
96
|
/** True when a bot with this provider still needs `hq bot auth` before it can answer. */
|
|
96
97
|
export declare function fleetProviderNeedsSignIn(provider: FleetLocalProfile["provider"]): boolean;
|
|
97
98
|
type FleetLocalExec = (executable: string, args: string[], options: Record<string, unknown>) => Buffer | string;
|
|
99
|
+
/** spawnSync-shaped runner for steps whose output is copied through after they finish. */
|
|
100
|
+
export type FleetLocalSpawn = (executable: string, args: string[], options: Record<string, unknown>) => {
|
|
101
|
+
status: number | null;
|
|
102
|
+
stdout?: Buffer | string | null;
|
|
103
|
+
stderr?: Buffer | string | null;
|
|
104
|
+
error?: Error;
|
|
105
|
+
};
|
|
98
106
|
export interface FleetLocalBootstrapDeps {
|
|
99
107
|
fleetHome?: string;
|
|
100
108
|
platform?: NodeJS.Platform;
|
|
101
109
|
run?: FleetLocalExec;
|
|
110
|
+
/** Runs the install steps whose output is copied through. Defaults to spawnSync, or to `run` when only `run` is given. */
|
|
111
|
+
spawn?: FleetLocalSpawn;
|
|
102
112
|
start?: boolean;
|
|
103
113
|
python?: FleetPython;
|
|
104
114
|
}
|
|
@@ -169,12 +179,23 @@ export declare const HQ_FLEET_LOCAL_RELEASE: FleetLocalReleasePin;
|
|
|
169
179
|
export declare const HQ_FLEET_LOCAL_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEASJoapvo0WMTg+Wu3Jvt0nzlXLOBEr+G1aJRi0JkEb4A=\n-----END PUBLIC KEY-----\n";
|
|
170
180
|
/** hq-fleet-local trust/release-public-v2.pem (added 2026-11-01; signs v0.4.18). */
|
|
171
181
|
export declare const HQ_FLEET_LOCAL_PUBLIC_KEY_V2 = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmgUi7pKTJUmf3yzwcuH65wSvn1NyJrDfZHZUX08sGN8=\n-----END PUBLIC KEY-----\n";
|
|
182
|
+
/** hq-fleet-local trust/release-public-v3.pem (added 2026-11-02; signs v0.4.20 and later). */
|
|
183
|
+
export declare const HQ_FLEET_LOCAL_PUBLIC_KEY_V3 = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA2NUo6F38D4Kjxmy5qz5ytKRVRwocEvPk8lXqfwB2kS0=\n-----END PUBLIC KEY-----\n";
|
|
172
184
|
/** Every key a release manifest may be signed with. Any one must verify it. */
|
|
173
185
|
export declare const HQ_FLEET_LOCAL_PUBLIC_KEYS: readonly string[];
|
|
174
186
|
/** True when any trusted Ed25519 key verifies the manifest signature. */
|
|
175
187
|
export declare function fleetLocalManifestSignatureValid(manifest: Buffer, signature: Buffer, publicKey?: string | readonly string[]): boolean;
|
|
176
188
|
export declare function fleetHome(home?: string, env?: NodeJS.ProcessEnv): string;
|
|
177
189
|
export declare function verifyFleetLocalRelease(files: FleetLocalReleaseFiles, release?: FleetLocalReleasePin, publicKey?: string | readonly string[]): void;
|
|
190
|
+
/**
|
|
191
|
+
* Check an extracted distribution against the signed manifest: every payload
|
|
192
|
+
* file present with its hash, and nothing else but the release metadata.
|
|
193
|
+
*/
|
|
194
|
+
export declare function verifyExtractedDistribution(dir: string, manifest: Buffer, version: string): void;
|
|
195
|
+
/** Write a ZIP archive's files under `target` with the same reader that verified it. */
|
|
196
|
+
export declare function extractZipEntries(archive: Buffer, target: string, version: string): void;
|
|
197
|
+
/** Every file in a ZIP archive by name (stored and deflated entries only; directories skipped). */
|
|
198
|
+
export declare function readZipEntries(archive: Buffer): Map<string, Buffer>;
|
|
178
199
|
/**
|
|
179
200
|
* Warning text when the signed manifest asks for a newer hq CLI than this
|
|
180
201
|
* one, or null. Advisory only: the pinned runtime is still installed, since
|
|
@@ -185,6 +206,45 @@ export declare function fleetLocalCliCompatibilityWarning(manifest: Buffer, rele
|
|
|
185
206
|
export declare const FLEET_RELEASE_TOKEN_TIMEOUT_MS = 15000;
|
|
186
207
|
export declare function resolveFleetReleaseToken(env?: NodeJS.ProcessEnv, run?: FleetLocalExec): string;
|
|
187
208
|
export declare function fetchHqFleetReleaseLinks(release: FleetLocalReleasePin): Promise<Map<string, string> | null>;
|
|
209
|
+
export declare const FLEET_LOCAL_LATEST_TIMEOUT_MS = 5000;
|
|
210
|
+
export declare const FLEET_LOCAL_LATEST_CACHE_MS: number;
|
|
211
|
+
export interface FleetLocalReleasePointer {
|
|
212
|
+
release: FleetLocalReleasePin;
|
|
213
|
+
minimumHqCli: string | null;
|
|
214
|
+
links: Map<string, string> | null;
|
|
215
|
+
linksExpireAt: number | null;
|
|
216
|
+
}
|
|
217
|
+
export interface FleetLocalTargetRelease {
|
|
218
|
+
release: FleetLocalReleasePin;
|
|
219
|
+
source: "pointer" | "compiled";
|
|
220
|
+
links: Map<string, string> | null;
|
|
221
|
+
linksExpireAt: number | null;
|
|
222
|
+
}
|
|
223
|
+
export declare function parseFleetLocalReleasePin(value: unknown): FleetLocalReleasePin | null;
|
|
224
|
+
export declare function parseFleetLocalReleasePointer(body: unknown, now?: number): FleetLocalReleasePointer | null;
|
|
225
|
+
export declare function chooseFleetLocalTargetRelease(pointer: FleetLocalReleasePointer | null, compiled?: FleetLocalReleasePin, cliVersion?: string): FleetLocalTargetRelease;
|
|
226
|
+
export declare function fetchFleetLocalReleasePointer(deps?: {
|
|
227
|
+
token?: () => Promise<string>;
|
|
228
|
+
fetchApi?: typeof vaultApiFetch;
|
|
229
|
+
now?: () => number;
|
|
230
|
+
}): Promise<FleetLocalReleasePointer | null>;
|
|
231
|
+
export declare function resetFleetLocalReleasePointerCache(): void;
|
|
232
|
+
interface FleetLocalPointerDeps {
|
|
233
|
+
fleetHome?: string;
|
|
234
|
+
now?: () => number;
|
|
235
|
+
fetchPointer?: () => Promise<FleetLocalReleasePointer | null>;
|
|
236
|
+
}
|
|
237
|
+
export declare function resolveFleetLocalTargetRelease(deps?: FleetLocalPointerDeps & {
|
|
238
|
+
compiled?: FleetLocalReleasePin;
|
|
239
|
+
cliVersion?: string;
|
|
240
|
+
}): Promise<FleetLocalTargetRelease>;
|
|
241
|
+
export declare function resolveFleetLocalPointerTarget(deps?: FleetLocalPointerDeps & {
|
|
242
|
+
cliVersion?: string;
|
|
243
|
+
}): Promise<FleetLocalTargetRelease | null>;
|
|
244
|
+
export declare function installTargetFleetLocalDistribution(deps?: Omit<FleetLocalInstallDeps, "release"> & {
|
|
245
|
+
target?: FleetLocalTargetRelease;
|
|
246
|
+
now?: () => number;
|
|
247
|
+
}): Promise<FleetLocalInstallation>;
|
|
188
248
|
export declare const FLEET_LOCAL_METADATA_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
189
249
|
export declare const FLEET_LOCAL_ARCHIVE_DOWNLOAD_TIMEOUT_MS: number;
|
|
190
250
|
export declare const FLEET_LOCAL_RUNTIME_DOWNLOAD_TIMEOUT_MS: number;
|
|
@@ -221,10 +281,42 @@ export declare function writeFleetLocalSoul(agentUid: string, systemPrompt: stri
|
|
|
221
281
|
* the bot's own interpreter, says beforehand what it would refuse.
|
|
222
282
|
*/
|
|
223
283
|
export declare function scanFleetLocalInstructions(agentUid: string, text: string, deps?: FleetLocalControlDeps): string[];
|
|
284
|
+
export declare function fleetLocalRuntimePython(agentUid: string, deps?: Pick<FleetLocalControlDeps, "fleetHome" | "platform">): {
|
|
285
|
+
python: string;
|
|
286
|
+
source: string;
|
|
287
|
+
profileDir: string;
|
|
288
|
+
};
|
|
289
|
+
export declare function fleetProfileOwnerCompanies(agentUid: string, deps?: Pick<FleetLocalControlDeps, "fleetHome">): string[];
|
|
290
|
+
export declare function fleetLocalProfileDir(agentUid: string, deps?: Pick<FleetLocalControlDeps, "fleetHome">): string;
|
|
291
|
+
export interface FleetLocalGatewayState {
|
|
292
|
+
pid: number | null;
|
|
293
|
+
gatewayState: string | null;
|
|
294
|
+
activeAgents: number;
|
|
295
|
+
platforms: Record<string, string>;
|
|
296
|
+
}
|
|
297
|
+
export declare function readFleetLocalGatewayState(agentUid: string, deps?: Pick<FleetLocalControlDeps, "fleetHome">): FleetLocalGatewayState | null;
|
|
298
|
+
export declare function fleetLocalChannels(state: FleetLocalGatewayState | null, gatewayAlive: boolean): {
|
|
299
|
+
slack: string;
|
|
300
|
+
telegram: string;
|
|
301
|
+
};
|
|
302
|
+
export declare function fleetLocalBusyReason(agentUid: string, deps?: Pick<FleetLocalControlDeps, "fleetHome"> & {
|
|
303
|
+
isAlive?: (pid: number) => boolean;
|
|
304
|
+
}): string | null;
|
|
224
305
|
/** Checks the instructions with the runtime's scanner, then makes them the bot's persona. */
|
|
225
306
|
export declare function refreshFleetLocalInstructions(agentUid: string, systemPrompt: string, deps?: FleetLocalControlDeps): string;
|
|
226
307
|
/** Last few non-empty stderr lines of a failed child process, trimmed for an error message. */
|
|
227
308
|
export declare function stderrTail(error: unknown): string;
|
|
309
|
+
/** A FleetLocalSpawn backed by an execFileSync-shaped runner (stderr is only known on failure). */
|
|
310
|
+
export declare function spawnFromRun(run: FleetLocalExec): FleetLocalSpawn;
|
|
311
|
+
/**
|
|
312
|
+
* Replaces inherited stdio slots (an fd number or "inherit") with "pipe".
|
|
313
|
+
* `forward` is true when any slot was replaced, so the caller copies the
|
|
314
|
+
* captured output to this process's stderr.
|
|
315
|
+
*/
|
|
316
|
+
export declare function pipeInheritedStdio(stdio: unknown): {
|
|
317
|
+
stdio: unknown;
|
|
318
|
+
forward: boolean;
|
|
319
|
+
};
|
|
228
320
|
/**
|
|
229
321
|
* Message for a Windows extraction that cannot fit under MAX_PATH, or null
|
|
230
322
|
* when it fits or long paths are on. `longest` is the longest member name in
|