@fastagent-sh/fastagent 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomic-write.d.ts +11 -7
- package/dist/atomic-write.js +16 -11
- package/dist/channels/agentcore-limits.d.ts +9 -0
- package/dist/channels/agentcore-limits.js +9 -0
- package/dist/channels/agentcore-service.d.ts +12 -11
- package/dist/channels/agentcore-service.js +14 -18
- package/dist/channels/agentcore.d.ts +11 -19
- package/dist/channels/agentcore.js +14 -7
- package/dist/channels/control.d.ts +50 -12
- package/dist/channels/control.js +239 -96
- package/dist/channels/discover.d.ts +26 -4
- package/dist/channels/discover.js +12 -23
- package/dist/channels/feishu/feishu-api.js +5 -8
- package/dist/channels/feishu/feishu.js +35 -18
- package/dist/channels/kit/attachment-path.d.ts +12 -0
- package/dist/channels/kit/attachment-path.js +43 -0
- package/dist/channels/kit/context-buffer.d.ts +9 -0
- package/dist/channels/kit/context-buffer.js +11 -0
- package/dist/channels/kit/signature.d.ts +12 -0
- package/dist/channels/kit/signature.js +17 -0
- package/dist/channels/kit/stop-command.js +3 -3
- package/dist/channels/kit/tasks.d.ts +1 -1
- package/dist/channels/kit/tasks.js +10 -4
- package/dist/channels/kit/turn-store.d.ts +19 -3
- package/dist/channels/kit/turn-store.js +29 -2
- package/dist/channels/slack/invoke-turn.d.ts +1 -1
- package/dist/channels/slack/invoke-turn.js +5 -1
- package/dist/channels/slack/onboard.js +5 -5
- package/dist/channels/slack/onboarding-state.d.ts +7 -3
- package/dist/channels/slack/onboarding-state.js +13 -20
- package/dist/channels/slack/register-webhook.js +1 -1
- package/dist/channels/slack/scaffold/slack-send.ts +2 -17
- package/dist/channels/slack/slack-api.js +22 -54
- package/dist/channels/slack/slack.js +13 -13
- package/dist/channels/telegram/parse.d.ts +21 -1
- package/dist/channels/telegram/parse.js +65 -11
- package/dist/channels/telegram/scaffold/channel.ts +7 -3
- package/dist/channels/telegram/telegram-api.js +5 -6
- package/dist/channels/telegram/telegram.d.ts +2 -2
- package/dist/channels/telegram/telegram.js +57 -69
- package/dist/cli/add-slack.js +6 -5
- package/dist/cli/commands/add.js +1 -5
- package/dist/cli/commands/attach.d.ts +2 -4
- package/dist/cli/commands/attach.js +17 -15
- package/dist/cli/commands/deploy.d.ts +50 -5
- package/dist/cli/commands/deploy.js +183 -134
- package/dist/cli/commands/dev.js +4 -31
- package/dist/cli/commands/info.js +1 -2
- package/dist/cli/commands/init.js +1 -2
- package/dist/cli/commands/start.js +31 -41
- package/dist/cli/serve.d.ts +12 -21
- package/dist/cli/serve.js +20 -25
- package/dist/cli/shared.d.ts +40 -10
- package/dist/cli/shared.js +51 -4
- package/dist/deploy/agentcore/logs.d.ts +2 -2
- package/dist/deploy/agentcore/logs.js +2 -2
- package/dist/deploy/agentcore/plan.d.ts +12 -10
- package/dist/deploy/agentcore/plan.js +39 -31
- package/dist/deploy/agentcore/run.d.ts +5 -4
- package/dist/deploy/agentcore/run.js +13 -36
- package/dist/deploy/channel-ingress.d.ts +73 -0
- package/dist/deploy/channel-ingress.js +101 -0
- package/dist/deploy/docker/plan.d.ts +3 -7
- package/dist/deploy/docker/plan.js +4 -15
- package/dist/deploy/docker/run.d.ts +18 -1
- package/dist/deploy/docker/run.js +10 -0
- package/dist/deploy/fly/plan.d.ts +4 -5
- package/dist/deploy/fly/plan.js +7 -22
- package/dist/deploy/fly/run.d.ts +9 -23
- package/dist/deploy/fly/run.js +32 -68
- package/dist/deploy/preflight.d.ts +6 -7
- package/dist/deploy/preflight.js +26 -22
- package/dist/deploy/railway/plan.d.ts +4 -5
- package/dist/deploy/railway/plan.js +11 -26
- package/dist/deploy/railway/run.d.ts +9 -9
- package/dist/deploy/railway/run.js +40 -40
- package/dist/deploy/runner.js +22 -2
- package/dist/deploy/secrets.d.ts +18 -9
- package/dist/deploy/secrets.js +64 -12
- package/dist/dev-supervisor.js +3 -4
- package/dist/engines/pi/agent-session-factory.js +20 -39
- package/dist/engines/pi/auth.js +43 -43
- package/dist/engines/pi/config.d.ts +1 -1
- package/dist/engines/pi/create.d.ts +14 -2
- package/dist/engines/pi/create.js +2 -2
- package/dist/engines/pi/definition.d.ts +1 -1
- package/dist/engines/pi/definition.js +3 -4
- package/dist/engines/pi/login.js +32 -16
- package/dist/engines/pi/open.d.ts +1 -2
- package/dist/engines/pi/open.js +1 -1
- package/dist/engines/pi/search-tools.js +1 -1
- package/dist/engines/pi/service.d.ts +1 -1
- package/dist/engines/pi/service.js +8 -0
- package/dist/engines/pi/session-builder.js +6 -33
- package/dist/engines/pi/session-control.d.ts +19 -6
- package/dist/engines/pi/session-control.js +565 -470
- package/dist/engines/pi/session-inheritance.d.ts +8 -22
- package/dist/engines/pi/session-inheritance.js +95 -76
- package/dist/engines/pi/session-markers.d.ts +48 -0
- package/dist/engines/pi/session-markers.js +59 -0
- package/dist/engines/pi/session-settings.d.ts +4 -4
- package/dist/engines/pi/session-settings.js +7 -4
- package/dist/engines/pi/session-store.d.ts +83 -13
- package/dist/engines/pi/session-store.js +408 -55
- package/dist/engines/pi/tool-context.d.ts +21 -8
- package/dist/engines/pi/tool-context.js +29 -4
- package/dist/engines/pi/tool.js +2 -2
- package/dist/env.js +1 -2
- package/dist/loader.d.ts +49 -7
- package/dist/loader.js +79 -18
- package/dist/paths.d.ts +19 -0
- package/dist/paths.js +27 -2
- package/dist/scaffold/add-channel.js +2 -2
- package/dist/scaffold/init.js +7 -2
- package/dist/scaffold/templates/tools/fetch-url.ts +0 -2
- package/dist/schedule/discover.js +3 -15
- package/dist/schedule/wake-alarm.d.ts +13 -7
- package/dist/schedule/wake-alarm.js +88 -46
- package/dist/schedule/wakeups.d.ts +1 -1
- package/dist/schedule/wakeups.js +10 -7
- package/dist/service.d.ts +1 -2
- package/dist/service.js +27 -5
- package/dist/session-remote.d.ts +7 -2
- package/dist/session-remote.js +162 -92
- package/dist/session.d.ts +226 -92
- package/dist/session.js +61 -23
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +18 -3
- package/dist/tunnel.js +32 -40
- package/package.json +1 -1
package/dist/cli/add-slack.js
CHANGED
|
@@ -27,7 +27,7 @@ export async function onboardSlackInternalApp(input) {
|
|
|
27
27
|
throw new Error("`add slack` needs an interactive terminal for internal-app creation and OAuth — " +
|
|
28
28
|
"re-run in a terminal, or pass --no-onboard to scaffold only");
|
|
29
29
|
}
|
|
30
|
-
let state =
|
|
30
|
+
let state = readSlackOnboardingState(input.stateRoot);
|
|
31
31
|
const resumed = state !== undefined;
|
|
32
32
|
if (input.replaceConfig && !state) {
|
|
33
33
|
throw new Error("--replace-config found no local Slack onboarding state on this machine — nothing to replace. " +
|
|
@@ -84,7 +84,7 @@ export async function onboardSlackInternalApp(input) {
|
|
|
84
84
|
if (!configToken.startsWith("xoxe.") || !configRefreshToken.startsWith("xoxe-")) {
|
|
85
85
|
throw new Error("invalid Slack configuration token prefix (expected xoxe. access + xoxe- refresh)");
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
writeSlackOnboardingState(input.stateRoot, {
|
|
88
88
|
...state,
|
|
89
89
|
configToken,
|
|
90
90
|
configRefreshToken,
|
|
@@ -116,11 +116,11 @@ export async function onboardSlackInternalApp(input) {
|
|
|
116
116
|
configToken,
|
|
117
117
|
configRefreshToken,
|
|
118
118
|
});
|
|
119
|
-
|
|
119
|
+
writeSlackOnboardingState(input.stateRoot, state);
|
|
120
120
|
}
|
|
121
121
|
else if (input.groupBehavior.explicit && !state.appId) {
|
|
122
122
|
state = { ...state, groupBehavior: input.groupBehavior.behavior };
|
|
123
|
-
|
|
123
|
+
writeSlackOnboardingState(input.stateRoot, state);
|
|
124
124
|
}
|
|
125
125
|
if (state.createAttemptedAt && !state.appId) {
|
|
126
126
|
throw new Error(`a prior Slack app creation attempt at ${state.createAttemptedAt} returned no app ID — ` +
|
|
@@ -144,6 +144,7 @@ export async function onboardSlackInternalApp(input) {
|
|
|
144
144
|
action = answer;
|
|
145
145
|
}
|
|
146
146
|
if (action === "replace-config") {
|
|
147
|
+
console.error(`[fastagent] generate a fresh App Configuration Token pair at ${CONFIG_TOKEN_URL}`);
|
|
147
148
|
openExternalUrl(CONFIG_TOKEN_URL);
|
|
148
149
|
state = {
|
|
149
150
|
...state,
|
|
@@ -154,7 +155,7 @@ export async function onboardSlackInternalApp(input) {
|
|
|
154
155
|
if (!state.configToken.startsWith("xoxe.") || !state.configRefreshToken.startsWith("xoxe-")) {
|
|
155
156
|
throw new Error("invalid Slack configuration token prefix (expected xoxe. access + xoxe- refresh)");
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
writeSlackOnboardingState(input.stateRoot, state);
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
const server = await startSlackSetupServer();
|
package/dist/cli/commands/add.js
CHANGED
|
@@ -8,13 +8,9 @@ import { join, relative, resolve } from "node:path";
|
|
|
8
8
|
import { isCancel, select } from "@clack/prompts";
|
|
9
9
|
import { onboardFeishuCloudApp } from "../add-feishu.js";
|
|
10
10
|
import { dotEnvPath, loadDotEnv } from "../../env.js";
|
|
11
|
-
import { resolveStateRoot } from "../../paths.js";
|
|
12
|
-
import { SECRETS_DIRNAME } from "../../paths.js";
|
|
11
|
+
import { resolveStateRoot, SECRETS_DIRNAME, isUnderDir, displayPath, exists } from "../../paths.js";
|
|
13
12
|
import { detectRuntime, readPackageJson } from "../../runtime.js";
|
|
14
|
-
import { isUnderDir } from "../../paths.js";
|
|
15
|
-
import { displayPath } from "../../paths.js";
|
|
16
13
|
import { appendChannelDotEnv, appendChannelEnv, assertChannelReady, channelExists, channelSetup, scaffoldChannel, } from "../../scaffold/add-channel.js";
|
|
17
|
-
import { exists } from "../../paths.js";
|
|
18
14
|
import { vendorSkill } from "../../scaffold/vendor-skill.js";
|
|
19
15
|
import { failStartup, failUsage, placementOrExit } from "../fail.js";
|
|
20
16
|
/** `fastagent add <kind> [dir]`: scaffold `channels/<kind>.ts` — the adapter import plus a starter `on()`. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SessionControl, type SessionEntry } from "../../session.ts";
|
|
2
2
|
export interface AttachOptions {
|
|
3
3
|
/** Override the control endpoint (skip control.json discovery) — for a remote serve. */
|
|
4
4
|
url?: string;
|
|
@@ -63,7 +63,7 @@ export interface AttachIo {
|
|
|
63
63
|
warn: (line: string) => void;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
-
* The backfill slice REDUCED TO THE ACTIVE PATH — a session is a tree (a
|
|
66
|
+
* The backfill slice REDUCED TO THE ACTIVE PATH — a session is a tree (a leaf move, or a
|
|
67
67
|
* compaction, leaves sibling branches behind), and printing the slice raw renders the abandoned
|
|
68
68
|
* branch interleaved with the live one as if it were one conversation. Reachability is computed
|
|
69
69
|
* backwards from the leaf; an entry whose parent lies BEFORE the slice is path-connected by
|
|
@@ -106,5 +106,3 @@ settleMs?: number): Promise<{
|
|
|
106
106
|
cursor: string | undefined;
|
|
107
107
|
sawProgress: boolean;
|
|
108
108
|
}>;
|
|
109
|
-
/** The cursor a failed round reached, if it recorded one. */
|
|
110
|
-
export declare function roundCursor(error: unknown): string | undefined;
|
|
@@ -16,7 +16,7 @@ import { loadDotEnv } from "../../env.js";
|
|
|
16
16
|
import { resolveStateRoot } from "../../paths.js";
|
|
17
17
|
import { log, setLogLevel } from "../../log.js";
|
|
18
18
|
import { ABORTED_CODE, SESSION_BUSY_CODE } from "../../agent.js";
|
|
19
|
-
import { NO_ACTIVE_RUN_CODE } from "../../session.js";
|
|
19
|
+
import { NO_ACTIVE_RUN_CODE, } from "../../session.js";
|
|
20
20
|
import { ControlRequestError, connectAgent, connectSessionControl } from "../../session-remote.js";
|
|
21
21
|
import { failStartup, placementOrExit } from "../fail.js";
|
|
22
22
|
/** Read the serving process's local discovery file. */
|
|
@@ -157,7 +157,7 @@ export async function runAttach(sessionArg, dirArg, opts) {
|
|
|
157
157
|
if (!endpoint)
|
|
158
158
|
endpoint = discover(dir); // discovered: the first read shares the budget
|
|
159
159
|
const connected = await connectSessionControl(endpoint);
|
|
160
|
-
return { control: connected, state: await connected.
|
|
160
|
+
return { control: connected, state: await connected.sessions.get(sessionArg).state() };
|
|
161
161
|
}
|
|
162
162
|
catch (error) {
|
|
163
163
|
const decision = decideRound(errorFacts(error), {
|
|
@@ -208,7 +208,7 @@ export async function runAttach(sessionArg, dirArg, opts) {
|
|
|
208
208
|
// ABORTED_CODE: a deliberate stop from ANY client (this attach's /abort, another attach, a
|
|
209
209
|
// Web panel) — the settled line reports it either way; no source discrimination here.
|
|
210
210
|
}
|
|
211
|
-
// session_busy = the LEASE is held — by another run OR a boundary mutation (compact/
|
|
211
|
+
// session_busy = the LEASE is held — by another run OR a boundary mutation (compact/update
|
|
212
212
|
// contend on the same lease); "a run started" would be a guess, and "steer it" bad advice
|
|
213
213
|
// against a compact. State the lease fact, promise nothing.
|
|
214
214
|
if (sawBusy)
|
|
@@ -225,12 +225,14 @@ export async function runAttach(sessionArg, dirArg, opts) {
|
|
|
225
225
|
void answerSlashInput(trimmed, control, (l) => console.log(l));
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
|
-
const
|
|
229
|
-
|
|
228
|
+
const stopping = trimmed === "/abort";
|
|
229
|
+
const label = stopping ? "abort" : "steer";
|
|
230
|
+
const session = control.sessions.get(sessionArg);
|
|
231
|
+
void (stopping ? session.abort() : session.steer({ text: trimmed })).then((result) => {
|
|
230
232
|
if (result.ok) {
|
|
231
|
-
console.log(`[${
|
|
233
|
+
console.log(`[${label} accepted]`);
|
|
232
234
|
}
|
|
233
|
-
else if (
|
|
235
|
+
else if (!stopping && result.error.code === NO_ACTIVE_RUN_CODE) {
|
|
234
236
|
// The invoke stream attach holds IS this run's driver (design: disconnect = cancel), so
|
|
235
237
|
// unlike channel-started runs, this one dies with the attach. Say so up front.
|
|
236
238
|
// Intent, not fact: admission may still fail (session_busy — the lease could be held
|
|
@@ -240,9 +242,9 @@ export async function runAttach(sessionArg, dirArg, opts) {
|
|
|
240
242
|
void startRun(trimmed).catch((error) => console.log(`[prompt failed: ${String(error)}]`));
|
|
241
243
|
}
|
|
242
244
|
else {
|
|
243
|
-
console.log(`[${
|
|
245
|
+
console.log(`[${label} rejected: ${result.error.code} — ${result.error.message}]`);
|
|
244
246
|
}
|
|
245
|
-
}, (error) => console.log(`[${
|
|
247
|
+
}, (error) => console.log(`[${label} failed: ${String(error)}]`));
|
|
246
248
|
});
|
|
247
249
|
// Every round has ONE shape: subscribe → backfill (render the durable record since the cursor)
|
|
248
250
|
// → drain live until the stream drops. Subscribing first + the server's eager registration
|
|
@@ -424,7 +426,7 @@ const isAuthError = (error) => error instanceof ControlRequestError && error.sta
|
|
|
424
426
|
* startup (a serve restart hours in), so the local name must not imply "startup only". */
|
|
425
427
|
const exitWith = failStartup;
|
|
426
428
|
/**
|
|
427
|
-
* The backfill slice REDUCED TO THE ACTIVE PATH — a session is a tree (a
|
|
429
|
+
* The backfill slice REDUCED TO THE ACTIVE PATH — a session is a tree (a leaf move, or a
|
|
428
430
|
* compaction, leaves sibling branches behind), and printing the slice raw renders the abandoned
|
|
429
431
|
* branch interleaved with the live one as if it were one conversation. Reachability is computed
|
|
430
432
|
* backwards from the leaf; an entry whose parent lies BEFORE the slice is path-connected by
|
|
@@ -437,7 +439,7 @@ export function activePathSlice(entries, leafEntryId) {
|
|
|
437
439
|
return entries;
|
|
438
440
|
const byId = new Map(entries.map((e) => [e.id, e]));
|
|
439
441
|
// An append always moves the leaf, so a leaf BEHIND the slice means every entry in it was
|
|
440
|
-
// appended and then abandoned — a
|
|
442
|
+
// appended and then abandoned — a leaf move backwards with no new turn since. Nothing here is on
|
|
441
443
|
// the active path.
|
|
442
444
|
if (!byId.has(leafEntryId))
|
|
443
445
|
return [];
|
|
@@ -509,7 +511,7 @@ settleMs = 300) {
|
|
|
509
511
|
// The round HOLDS its subscription's iterator: one round = one stream, on every path — a
|
|
510
512
|
// backfill failure must close it before propagating, or the caller's retry round would stack a
|
|
511
513
|
// second concurrent stream interleaving the same session's output.
|
|
512
|
-
const iterator = control.
|
|
514
|
+
const iterator = control.sessions.get(session).events()[Symbol.asyncIterator]();
|
|
513
515
|
// Live output is BUFFERED while the replay block prints, then flushed — the drain runs
|
|
514
516
|
// concurrently with the backfill, and interleaving raw deltas into the labeled replay would make
|
|
515
517
|
// both unreadable; the [end of replay] label is only honest if the block is contiguous.
|
|
@@ -554,7 +556,7 @@ settleMs = 300) {
|
|
|
554
556
|
let next = cursor;
|
|
555
557
|
let sawBackfill = false;
|
|
556
558
|
try {
|
|
557
|
-
const backfill = await control.entries(
|
|
559
|
+
const backfill = await control.sessions.get(session).entries(cursor !== undefined ? { since: cursor } : undefined);
|
|
558
560
|
sawBackfill = backfill.entries.length > 0;
|
|
559
561
|
// Advance by APPEND ORDER (the last returned record), never by leafEntryId: `since` is an
|
|
560
562
|
// append-position cursor (design §7), and a leaf that sits before later appends (abandoned
|
|
@@ -579,7 +581,7 @@ settleMs = 300) {
|
|
|
579
581
|
}
|
|
580
582
|
// The protocol's reconnect step the replay cannot cover: status changes while away are
|
|
581
583
|
// LIVE-only events (state_changed before a restart is neither replayed nor re-emitted).
|
|
582
|
-
const now = await control.
|
|
584
|
+
const now = await control.sessions.get(session).state();
|
|
583
585
|
io.println(`[live — ${now.status}${now.activeRunId ? ` (run ${now.activeRunId})` : ""}]`);
|
|
584
586
|
}
|
|
585
587
|
catch (error) {
|
|
@@ -612,7 +614,7 @@ function withCursor(error, cursor) {
|
|
|
612
614
|
return Object.assign(e, { attachCursor: cursor });
|
|
613
615
|
}
|
|
614
616
|
/** The cursor a failed round reached, if it recorded one. */
|
|
615
|
-
|
|
617
|
+
function roundCursor(error) {
|
|
616
618
|
return error.attachCursor;
|
|
617
619
|
}
|
|
618
620
|
/** Render one durable record on replay — the guaranteed kind vocabulary; other kinds are skipped. */
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/** The deploy targets, as a value: {@link HOST_ONLY_FLAGS} is checked against this list by a test, and
|
|
2
|
+
* a type alone cannot be enumerated at runtime. NOT the only copy — `cli/program.ts` repeats it as the
|
|
3
|
+
* `<host>` argument's `choices`, because that file may not import a command module at load time (its
|
|
4
|
+
* per-command imports are lazy). Adding a host means editing both; the type there rides in on a
|
|
5
|
+
* `import type`, which costs nothing at runtime. */
|
|
6
|
+
export declare const DEPLOY_HOSTS: readonly ["docker", "fly", "railway", "agentcore"];
|
|
7
|
+
export type DeployHost = (typeof DEPLOY_HOSTS)[number];
|
|
2
8
|
export interface DeployOptions {
|
|
3
9
|
run?: boolean;
|
|
4
10
|
tunnel?: boolean;
|
|
@@ -12,12 +18,50 @@ export interface DeployOptions {
|
|
|
12
18
|
/** false ⇔ `--no-input`. */
|
|
13
19
|
input?: boolean;
|
|
14
20
|
}
|
|
21
|
+
/** A flag exactly one host honours, and what the OTHERS do instead. `instead` is exhaustive over the
|
|
22
|
+
* non-owners, so a host added to {@link DEPLOY_HOSTS} cannot silently lose its line. */
|
|
23
|
+
interface HostOnlyFlag<Owner extends DeployHost> {
|
|
24
|
+
flag: string;
|
|
25
|
+
owner: Owner;
|
|
26
|
+
passed: (opts: DeployOptions) => boolean;
|
|
27
|
+
instead: Record<Exclude<DeployHost, Owner>, string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* ONE table for "this flag belongs to that host", because the fact is symmetric and was not stored
|
|
31
|
+
* that way: each host branch stated the OTHER hosts' flags in its own words, so the same sentence
|
|
32
|
+
* existed three times per flag and had already drifted (`Railway-only` twice, `railway-only` once).
|
|
33
|
+
*
|
|
34
|
+
* Every row is a flag that only WARNS elsewhere. `--tunnel` is host-only too and is deliberately not
|
|
35
|
+
* here: it is a usage GATE (`failUsage`, exit 2) raised in `runDeploy`, not a warning — moving it in
|
|
36
|
+
* would downgrade a refusal to a line of advice.
|
|
37
|
+
*
|
|
38
|
+
* Exported for the exhaustiveness test: the type stops a missing `instead` line, and the test stops it
|
|
39
|
+
* from being typed away.
|
|
40
|
+
*/
|
|
41
|
+
export declare const HOST_ONLY_FLAGS: (HostOnlyFlag<"fly"> | HostOnlyFlag<"railway">)[];
|
|
42
|
+
/** Exported for its own test: nothing covered these six sentences, which is how three of them came to
|
|
43
|
+
* disagree about the spelling of a host name. */
|
|
44
|
+
export declare function warnHostOnlyFlags(host: DeployHost, opts: DeployOptions): void;
|
|
15
45
|
export declare function runDeploy(host: DeployHost, dirArg: string, opts: DeployOptions): Promise<void>;
|
|
16
46
|
/**
|
|
17
|
-
* Write
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
47
|
+
* Write each generated artifact under `target`, under ONE ownership rule: **deploy only ever overwrites
|
|
48
|
+
* its own output.** Each generated file opens with a marker, so a file on disk is either OURS (a previous
|
|
49
|
+
* `deploy` wrote it) or the author's — and `--force` means "my generated artifact is authoritative",
|
|
50
|
+
* which never licenses clobbering a file we did not write. To hand a path back to fastagent, delete it.
|
|
51
|
+
*
|
|
52
|
+
* That single rule replaced a second mechanism (a per-host list of paths exempt from `--force`), which
|
|
53
|
+
* only described one shape: with the agent inside the workspace, the root `.dockerignore` is the
|
|
54
|
+
* WORKSPACE's file and was listed; with the agent flat, the list was empty — so `--force` would have
|
|
55
|
+
* overwritten a hand-written root `Dockerfile` in a repository `init --flat` had explicitly adopted.
|
|
56
|
+
* Ownership is a property of the file, not of where the agent sits.
|
|
57
|
+
*
|
|
58
|
+
* A KEPT file of OURS that no longer matches what deploy would generate now (config/channel/lockfile/
|
|
59
|
+
* version drift — or the author's edits, which we cannot tell apart) is flagged stale; `--force`
|
|
60
|
+
* regenerates that one.
|
|
61
|
+
*
|
|
62
|
+
* Exported for its own test — this is a four-branch state machine over (exists, ours, force) that used
|
|
63
|
+
* to be proven by spawning the CLI eight times, which is command LOGIC re-run through a subprocess
|
|
64
|
+
* (see vitest.config.ts) and the suite's slowest test.
|
|
21
65
|
*/
|
|
22
66
|
export declare function writeArtifacts(target: string, artifacts: {
|
|
23
67
|
path: string;
|
|
@@ -26,3 +70,4 @@ export declare function writeArtifacts(target: string, artifacts: {
|
|
|
26
70
|
force: boolean;
|
|
27
71
|
alwaysWrite?: string[];
|
|
28
72
|
}): Promise<void>;
|
|
73
|
+
export {};
|