@cluesmith/codev 3.3.1 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard-dist/assets/{index-D3XaKpZW.js → index-CUIjS_Vb.js} +41 -41
- package/dashboard-dist/assets/index-CUIjS_Vb.js.map +1 -0
- package/dashboard-dist/assets/index-DnYLy5C_.css +32 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +52 -1
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/inbox.d.ts.map +1 -1
- package/dist/agent-farm/commands/inbox.js +67 -10
- package/dist/agent-farm/commands/inbox.js.map +1 -1
- package/dist/agent-farm/commands/interrupt.d.ts +4 -1
- package/dist/agent-farm/commands/interrupt.d.ts.map +1 -1
- package/dist/agent-farm/commands/interrupt.js +6 -3
- package/dist/agent-farm/commands/interrupt.js.map +1 -1
- package/dist/agent-farm/commands/reset/constants.d.ts +118 -0
- package/dist/agent-farm/commands/reset/constants.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset/constants.js +118 -0
- package/dist/agent-farm/commands/reset/constants.js.map +1 -1
- package/dist/agent-farm/commands/reset/context.d.ts +18 -0
- package/dist/agent-farm/commands/reset/context.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset/context.js +41 -0
- package/dist/agent-farm/commands/reset/context.js.map +1 -1
- package/dist/agent-farm/commands/reset/receipt.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset/receipt.js +16 -5
- package/dist/agent-farm/commands/reset/receipt.js.map +1 -1
- package/dist/agent-farm/commands/reset/reorient.d.ts +1 -1
- package/dist/agent-farm/commands/reset/reorient.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset/reorient.js +8 -1
- package/dist/agent-farm/commands/reset/reorient.js.map +1 -1
- package/dist/agent-farm/commands/reset/self.d.ts +335 -0
- package/dist/agent-farm/commands/reset/self.d.ts.map +1 -0
- package/dist/agent-farm/commands/reset/self.js +636 -0
- package/dist/agent-farm/commands/reset/self.js.map +1 -0
- package/dist/agent-farm/commands/reset.d.ts +4 -1
- package/dist/agent-farm/commands/reset.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset.js +29 -21
- package/dist/agent-farm/commands/reset.js.map +1 -1
- package/dist/agent-farm/commands/self-refresh.d.ts +60 -0
- package/dist/agent-farm/commands/self-refresh.d.ts.map +1 -0
- package/dist/agent-farm/commands/self-refresh.js +506 -0
- package/dist/agent-farm/commands/self-refresh.js.map +1 -0
- package/dist/agent-farm/commands/send.d.ts +28 -0
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +90 -7
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/commands/spawn.d.ts +7 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +13 -1
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/db/index.d.ts +3 -1
- package/dist/agent-farm/db/index.d.ts.map +1 -1
- package/dist/agent-farm/db/index.js +8 -443
- package/dist/agent-farm/db/index.js.map +1 -1
- package/dist/agent-farm/db/mailbox.d.ts +47 -7
- package/dist/agent-farm/db/mailbox.d.ts.map +1 -1
- package/dist/agent-farm/db/mailbox.js +56 -12
- package/dist/agent-farm/db/mailbox.js.map +1 -1
- package/dist/agent-farm/db/migrations.d.ts +57 -0
- package/dist/agent-farm/db/migrations.d.ts.map +1 -0
- package/dist/agent-farm/db/migrations.js +530 -0
- package/dist/agent-farm/db/migrations.js.map +1 -0
- package/dist/agent-farm/db/schema.d.ts +1 -1
- package/dist/agent-farm/db/schema.d.ts.map +1 -1
- package/dist/agent-farm/db/schema.js +1 -0
- package/dist/agent-farm/db/schema.js.map +1 -1
- package/dist/agent-farm/db/types.d.ts +22 -0
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/lib/tower-client.d.ts +12 -0
- package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tower-client.js +12 -0
- package/dist/agent-farm/lib/tower-client.js.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.js +43 -14
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
- package/dist/agent-farm/servers/cron-delivery.d.ts +7 -1
- package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -1
- package/dist/agent-farm/servers/cron-delivery.js +2 -1
- package/dist/agent-farm/servers/cron-delivery.js.map +1 -1
- package/dist/agent-farm/servers/gate-profiles.d.ts +21 -0
- package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -1
- package/dist/agent-farm/servers/gate-profiles.js +36 -4
- package/dist/agent-farm/servers/gate-profiles.js.map +1 -1
- package/dist/agent-farm/servers/mailbox-delivery.d.ts +218 -15
- package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-delivery.js +259 -27
- package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.d.ts +66 -11
- package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -1
- package/dist/agent-farm/servers/mailbox-wiring.js +202 -48
- package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -1
- package/dist/agent-farm/servers/message-write.d.ts +58 -18
- package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
- package/dist/agent-farm/servers/message-write.js +73 -28
- package/dist/agent-farm/servers/message-write.js.map +1 -1
- package/dist/agent-farm/servers/render-gate.d.ts +37 -1
- package/dist/agent-farm/servers/render-gate.d.ts.map +1 -1
- package/dist/agent-farm/servers/render-gate.js +71 -12
- package/dist/agent-farm/servers/render-gate.js.map +1 -1
- package/dist/agent-farm/servers/session-submit.d.ts +220 -27
- package/dist/agent-farm/servers/session-submit.d.ts.map +1 -1
- package/dist/agent-farm/servers/session-submit.js +333 -42
- package/dist/agent-farm/servers/session-submit.js.map +1 -1
- package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-cron.js +3 -2
- package/dist/agent-farm/servers/tower-cron.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +11 -3
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts +32 -0
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +245 -36
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +15 -2
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts +21 -0
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.js +53 -5
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
- package/dist/agent-farm/servers/tower-tunnel.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-tunnel.js +14 -0
- package/dist/agent-farm/servers/tower-tunnel.js.map +1 -1
- package/dist/agent-farm/servers/tower-utils.d.ts +35 -0
- package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-utils.js +39 -0
- package/dist/agent-farm/servers/tower-utils.js.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.js +8 -1
- package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
- package/dist/agent-farm/types.d.ts +36 -1
- package/dist/agent-farm/types.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.d.ts +136 -4
- package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.js +212 -22
- package/dist/agent-farm/utils/message-format.js.map +1 -1
- package/dist/agent-farm/utils/server-utils.d.ts +8 -2
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +19 -2
- package/dist/agent-farm/utils/server-utils.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/generate-image.d.ts +20 -1
- package/dist/commands/generate-image.d.ts.map +1 -1
- package/dist/commands/generate-image.js +188 -1
- package/dist/commands/generate-image.js.map +1 -1
- package/dist/commands/porch/context-refresh.d.ts +181 -0
- package/dist/commands/porch/context-refresh.d.ts.map +1 -0
- package/dist/commands/porch/context-refresh.js +270 -0
- package/dist/commands/porch/context-refresh.js.map +1 -0
- package/dist/commands/porch/index.d.ts +6 -0
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +46 -0
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/next.d.ts +0 -9
- package/dist/commands/porch/next.d.ts.map +1 -1
- package/dist/commands/porch/next.js +133 -4
- package/dist/commands/porch/next.js.map +1 -1
- package/dist/commands/porch/prompts.d.ts.map +1 -1
- package/dist/commands/porch/prompts.js +18 -2
- package/dist/commands/porch/prompts.js.map +1 -1
- package/dist/commands/porch/protocol.d.ts.map +1 -1
- package/dist/commands/porch/protocol.js +102 -0
- package/dist/commands/porch/protocol.js.map +1 -1
- package/dist/commands/porch/types.d.ts +61 -0
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/lib/forge-contracts.d.ts +66 -5
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/forge.d.ts +1 -1
- package/dist/lib/forge.d.ts.map +1 -1
- package/dist/lib/forge.js +33 -11
- package/dist/lib/forge.js.map +1 -1
- package/dist/lib/self-refresh-invocation.d.ts +60 -0
- package/dist/lib/self-refresh-invocation.d.ts.map +1 -0
- package/dist/lib/self-refresh-invocation.js +64 -0
- package/dist/lib/self-refresh-invocation.js.map +1 -0
- package/dist/lib/test-env.d.ts +50 -0
- package/dist/lib/test-env.d.ts.map +1 -1
- package/dist/lib/test-env.js +76 -0
- package/dist/lib/test-env.js.map +1 -1
- package/dist/terminal/pty-manager.d.ts +10 -1
- package/dist/terminal/pty-manager.d.ts.map +1 -1
- package/dist/terminal/pty-manager.js +38 -9
- package/dist/terminal/pty-manager.js.map +1 -1
- package/dist/terminal/pty-session.d.ts +52 -4
- package/dist/terminal/pty-session.d.ts.map +1 -1
- package/dist/terminal/pty-session.js +157 -18
- package/dist/terminal/pty-session.js.map +1 -1
- package/dist/terminal/shellper-client.d.ts +73 -0
- package/dist/terminal/shellper-client.d.ts.map +1 -1
- package/dist/terminal/shellper-client.js +151 -0
- package/dist/terminal/shellper-client.js.map +1 -1
- package/dist/terminal/shellper-main.js +20 -3
- package/dist/terminal/shellper-main.js.map +1 -1
- package/dist/terminal/shellper-process.d.ts +2 -0
- package/dist/terminal/shellper-process.d.ts.map +1 -1
- package/dist/terminal/shellper-process.js +17 -1
- package/dist/terminal/shellper-process.js.map +1 -1
- package/dist/terminal/shellper-protocol.d.ts +28 -0
- package/dist/terminal/shellper-protocol.d.ts.map +1 -1
- package/dist/terminal/shellper-protocol.js.map +1 -1
- package/package.json +4 -4
- package/scripts/forge/gitea/_lib.sh +214 -0
- package/scripts/forge/gitea/issue-comment.sh +8 -1
- package/scripts/forge/gitea/issue-view.sh +95 -4
- package/scripts/forge/gitea/pr-create.sh +155 -0
- package/scripts/forge/gitea/pr-exists.sh +32 -4
- package/scripts/forge/gitea/pr-list.sh +40 -31
- package/scripts/forge/gitea/pr-view.sh +65 -4
- package/scripts/forge/gitea/recently-merged.sh +91 -21
- package/scripts/forge/gitea/user-identity.sh +30 -1
- package/scripts/forge/github/issue-view.sh +5 -2
- package/scripts/forge/github/pr-create.sh +47 -0
- package/scripts/forge/github/pr-search.sh +3 -1
- package/scripts/forge/gitlab/issue-view.sh +24 -4
- package/scripts/forge/gitlab/pr-create.sh +53 -0
- package/scripts/forge/gitlab/pr-search.sh +3 -1
- package/scripts/forge/linear/issue-view.sh +13 -2
- package/skeleton/.claude/skills/arch-save/SKILL.md +8 -2
- package/skeleton/.claude/skills/builder-refresh/SKILL.md +138 -0
- package/skeleton/.claude/skills/generate-image/SKILL.md +22 -1
- package/skeleton/.codex/skills/arch-save/SKILL.md +8 -2
- package/skeleton/.codex/skills/builder-refresh/SKILL.md +138 -0
- package/skeleton/.codex/skills/generate-image/SKILL.md +22 -1
- package/skeleton/protocol-schema.json +17 -0
- package/skeleton/protocols/air/prompts/pr.md +6 -1
- package/skeleton/protocols/air/protocol.json +1 -1
- package/skeleton/protocols/aspir/prompts/review.md +6 -1
- package/skeleton/protocols/aspir/protocol.json +5 -1
- package/skeleton/protocols/bugfix/prompts/pr.md +6 -1
- package/skeleton/protocols/bugfix/protocol.json +1 -1
- package/skeleton/protocols/bugfix/protocol.md +2 -1
- package/skeleton/protocols/experiment/protocol.json +1 -1
- package/skeleton/protocols/maintain/prompts/review.md +6 -1
- package/skeleton/protocols/maintain/protocol.json +1 -1
- package/skeleton/protocols/pir/prompts/review.md +10 -7
- package/skeleton/protocols/pir/protocol.json +1 -1
- package/skeleton/protocols/protocol-schema.json +17 -0
- package/skeleton/protocols/research/protocol.json +1 -1
- package/skeleton/protocols/spike/protocol.json +1 -1
- package/skeleton/protocols/spir/prompts/review.md +6 -1
- package/skeleton/protocols/spir/protocol.json +5 -1
- package/skeleton/resources/commands/agent-farm.md +1 -1
- package/templates/tower.html +16 -1
- package/dashboard-dist/assets/index-BZRTEMtH.css +0 -32
- package/dashboard-dist/assets/index-D3XaKpZW.js.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* generate-image - AI-powered image generation using Google's Gemini model (Nano Banana Pro)
|
|
3
3
|
*
|
|
4
|
-
* Uses the @google/genai SDK with GEMINI_API_KEY from environment.
|
|
4
|
+
* Uses the @google/genai SDK with GEMINI_API_KEY from environment. Atlas Cloud
|
|
5
|
+
* serves the same model over a submit-then-poll REST API and is available as an
|
|
6
|
+
* opt-in provider with ATLASCLOUD_API_KEY.
|
|
5
7
|
*/
|
|
6
8
|
import { GoogleGenAI } from '@google/genai';
|
|
7
9
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
@@ -13,6 +15,24 @@ const MODEL = 'gemini-3-pro-image-preview';
|
|
|
13
15
|
const RESOLUTIONS = ['1K', '2K', '4K'];
|
|
14
16
|
// Valid aspect ratios
|
|
15
17
|
const ASPECT_RATIOS = ['1:1', '16:9', '9:16', '3:4', '4:3', '3:2', '2:3'];
|
|
18
|
+
// Providers serving the same model
|
|
19
|
+
const PROVIDERS = ['gemini', 'atlas'];
|
|
20
|
+
// Atlas Cloud serves the same Nano Banana Pro model over its own async REST API
|
|
21
|
+
const ATLAS_BASE_URL = 'https://api.atlascloud.ai/api/v1/model';
|
|
22
|
+
const ATLAS_MODEL = 'google/nano-banana-pro/text-to-image';
|
|
23
|
+
const ATLAS_POLL_INTERVAL_MS = 5000;
|
|
24
|
+
const ATLAS_TIMEOUT_MS = 300_000;
|
|
25
|
+
// Per-request bounds. ATLAS_TIMEOUT_MS caps the poll loop as a whole, but it is
|
|
26
|
+
// only checked between requests, so each fetch carries its own deadline.
|
|
27
|
+
const ATLAS_REQUEST_TIMEOUT_MS = 30_000;
|
|
28
|
+
const ATLAS_DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
29
|
+
// The only status Atlas documents for a prediction that is still running
|
|
30
|
+
// (https://www.atlascloud.ai/docs/en/predictions lists exactly processing,
|
|
31
|
+
// completed and failed). Anything else is unrecognized and fails, named.
|
|
32
|
+
const ATLAS_IN_PROGRESS_STATUSES = new Set(['processing']);
|
|
33
|
+
// api.atlascloud.ai rejects some clients' default User-Agent with 403 (error
|
|
34
|
+
// code 1010), so every request sends an explicit one.
|
|
35
|
+
const ATLAS_USER_AGENT = 'codev-generate-image/1';
|
|
16
36
|
/**
|
|
17
37
|
* Get the Google GenAI client using API key from environment
|
|
18
38
|
*/
|
|
@@ -38,6 +58,162 @@ function readPrompt(promptOrPath) {
|
|
|
38
58
|
}
|
|
39
59
|
return promptOrPath;
|
|
40
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Check that the downloaded bytes really are an image, and name the file after
|
|
63
|
+
* the container they turned out to be.
|
|
64
|
+
*
|
|
65
|
+
* Atlas serves whatever container the model produced (JPEG for Nano Banana
|
|
66
|
+
* Pro), so writing those bytes into the default `output.png` would mislabel
|
|
67
|
+
* the file. Bytes that are not a recognised image are not written at all: a
|
|
68
|
+
* 200 response carrying an HTML error body must never land in output.png
|
|
69
|
+
* under a green "Image saved". Exits rather than returning on that path.
|
|
70
|
+
*/
|
|
71
|
+
function targetPathForImageBytes(output, bytes) {
|
|
72
|
+
const detected = bytes.subarray(0, 3).toString('hex') === 'ffd8ff'
|
|
73
|
+
? 'jpg'
|
|
74
|
+
: bytes.subarray(0, 8).toString('hex') === '89504e470d0a1a0a'
|
|
75
|
+
? 'png'
|
|
76
|
+
: bytes.subarray(0, 4).toString('ascii') === 'RIFF' &&
|
|
77
|
+
bytes.subarray(8, 12).toString('ascii') === 'WEBP'
|
|
78
|
+
? 'webp'
|
|
79
|
+
: null;
|
|
80
|
+
if (!detected) {
|
|
81
|
+
console.error(chalk.red('Error:') +
|
|
82
|
+
` Atlas returned ${bytes.length} bytes that are not a JPEG, PNG or WebP image` +
|
|
83
|
+
` (starts with ${bytes.subarray(0, 8).toString('hex') || '<empty>'}).` +
|
|
84
|
+
' Nothing was written.');
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const current = output.toLowerCase().split('.').pop();
|
|
88
|
+
if (current === detected || (detected === 'jpg' && current === 'jpeg'))
|
|
89
|
+
return output;
|
|
90
|
+
const renamed = output.replace(/\.[^./\\]+$/, '') + '.' + detected;
|
|
91
|
+
console.log(chalk.yellow('Note:') + ` provider returned ${detected.toUpperCase()}; saving as ${renamed}`);
|
|
92
|
+
return renamed;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* One Atlas exchange - connect, stream and parse - under a single deadline.
|
|
96
|
+
*
|
|
97
|
+
* ATLAS_TIMEOUT_MS bounds the poll loop as a whole, but it is only checked
|
|
98
|
+
* between requests: without a signal, a single stalled connection hangs the
|
|
99
|
+
* command forever. The signal also stays armed while the body streams, so the
|
|
100
|
+
* body read belongs inside the guard too - otherwise a poll that answers 200
|
|
101
|
+
* with an HTML error page, or a download aborted mid-stream, escapes as a raw
|
|
102
|
+
* SyntaxError or TimeoutError stack instead of a clear message.
|
|
103
|
+
*/
|
|
104
|
+
async function atlasRequest(url, what, timeoutMs, read, init = {}) {
|
|
105
|
+
// Resolved inside the try, acted on outside it, so that reporting a failure
|
|
106
|
+
// never lands in our own catch.
|
|
107
|
+
let outcome;
|
|
108
|
+
try {
|
|
109
|
+
const response = await fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
110
|
+
outcome = response.ok
|
|
111
|
+
? { ok: true, body: await read(response) }
|
|
112
|
+
: { ok: false, detail: ` (${response.status}): ${await response.text()}` };
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
outcome = {
|
|
116
|
+
ok: false,
|
|
117
|
+
detail: error instanceof Error && error.name === 'TimeoutError'
|
|
118
|
+
? `: no response within ${timeoutMs}ms`
|
|
119
|
+
: `: ${error instanceof Error ? error.message : String(error)}`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (!outcome.ok) {
|
|
123
|
+
console.error(chalk.red('Error:') + ` Atlas ${what} failed${outcome.detail}`.trimEnd());
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
return outcome.body;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Generate through Atlas Cloud: submit a job, poll the prediction, download.
|
|
130
|
+
*
|
|
131
|
+
* The cadence and the overall budget are parameters rather than constants so
|
|
132
|
+
* tests can drive the loop without sleeping for real. Nothing but tests passes
|
|
133
|
+
* them; the CLI uses the defaults.
|
|
134
|
+
*/
|
|
135
|
+
export async function generateViaAtlas(promptText, output, aspect, resolution, refs, options = {}) {
|
|
136
|
+
const pollIntervalMs = options.pollIntervalMs ?? ATLAS_POLL_INTERVAL_MS;
|
|
137
|
+
const timeoutMs = options.timeoutMs ?? ATLAS_TIMEOUT_MS;
|
|
138
|
+
// Argument problems are reported before credential problems, so that
|
|
139
|
+
// `--provider atlas --ref x` names the unsupported flag rather than a
|
|
140
|
+
// missing key the user would not have needed anyway.
|
|
141
|
+
if (refs.length > 0) {
|
|
142
|
+
console.error(chalk.red('Error:') +
|
|
143
|
+
' --ref is not supported with --provider atlas (this path is text-to-image only).\n' +
|
|
144
|
+
'Use --provider gemini for reference images.');
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
const apiKey = process.env.ATLASCLOUD_API_KEY;
|
|
148
|
+
if (!apiKey) {
|
|
149
|
+
console.error(chalk.red('Error:') +
|
|
150
|
+
' ATLASCLOUD_API_KEY environment variable not set.\n' +
|
|
151
|
+
'Get an API key at https://www.atlascloud.ai/console');
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
// Measured against the endpoint: aspect_ratio is honoured (1:1 -> 1024x1024,
|
|
155
|
+
// 16:9 -> 1376x768), while 1K/2K/4K has no equivalent field here.
|
|
156
|
+
if (resolution !== '1K') {
|
|
157
|
+
console.log(chalk.yellow('Note:') +
|
|
158
|
+
` --resolution ${resolution} is not exposed by this provider; the model's default resolution is returned.`);
|
|
159
|
+
}
|
|
160
|
+
const headers = {
|
|
161
|
+
Authorization: `Bearer ${apiKey}`,
|
|
162
|
+
'Content-Type': 'application/json',
|
|
163
|
+
'User-Agent': ATLAS_USER_AGENT,
|
|
164
|
+
};
|
|
165
|
+
const submitted = (await atlasRequest(`${ATLAS_BASE_URL}/generateImage`, 'submit', ATLAS_REQUEST_TIMEOUT_MS, (response) => response.json(), {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers,
|
|
168
|
+
body: JSON.stringify({ model: ATLAS_MODEL, prompt: promptText, aspect_ratio: aspect }),
|
|
169
|
+
}));
|
|
170
|
+
const predictionId = submitted?.data?.id;
|
|
171
|
+
if (typeof predictionId !== 'string' || predictionId === '') {
|
|
172
|
+
console.error(chalk.red('Error:') + ' Atlas did not return a prediction id');
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
const deadline = Date.now() + timeoutMs;
|
|
176
|
+
for (;;) {
|
|
177
|
+
await new Promise((done) => setTimeout(done, pollIntervalMs));
|
|
178
|
+
// Checked after the sleep, not before it: a pre-sleep check can pass on a
|
|
179
|
+
// budget that expires during the sleep, and then spend a whole further
|
|
180
|
+
// request on it.
|
|
181
|
+
if (Date.now() >= deadline) {
|
|
182
|
+
console.error(chalk.red('Error:') + ` Atlas prediction ${predictionId} timed out after ${timeoutMs}ms`);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
const polled = (await atlasRequest(`${ATLAS_BASE_URL}/prediction/${encodeURIComponent(predictionId)}`, 'poll', ATLAS_REQUEST_TIMEOUT_MS, (response) => response.json(), { headers }));
|
|
186
|
+
const status = polled?.data?.status;
|
|
187
|
+
if (status === 'completed') {
|
|
188
|
+
const url = polled?.data?.outputs?.[0];
|
|
189
|
+
if (typeof url !== 'string' || url === '') {
|
|
190
|
+
console.error(chalk.red('Error:') + ' Atlas completed without an image URL');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
// No Atlas headers here: the CDN is a different origin and must never
|
|
194
|
+
// see the API key.
|
|
195
|
+
const bytes = Buffer.from(await atlasRequest(url, 'image download', ATLAS_DOWNLOAD_TIMEOUT_MS, (response) => response.arrayBuffer()));
|
|
196
|
+
const target = targetPathForImageBytes(output, bytes);
|
|
197
|
+
writeFileSync(target, bytes);
|
|
198
|
+
console.log(chalk.green('Image saved to') + ` ${target}`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (status === 'failed') {
|
|
202
|
+
const detail = polled?.data?.error;
|
|
203
|
+
console.error(chalk.red('Error:') +
|
|
204
|
+
` Atlas generation failed: ${typeof detail === 'string' && detail !== '' ? detail : 'unknown'}`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
if (typeof status !== 'string' || !ATLAS_IN_PROGRESS_STATUSES.has(status)) {
|
|
208
|
+
// Polling on past a status we don't understand burns the full timeout and
|
|
209
|
+
// then reports it as one, which is a lie about what happened.
|
|
210
|
+
console.error(chalk.red('Error:') +
|
|
211
|
+
` Atlas prediction ${predictionId} reported an unrecognized status: ` +
|
|
212
|
+
(status === undefined ? '(none)' : String(status)));
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
41
217
|
/**
|
|
42
218
|
* Main generate-image function
|
|
43
219
|
*/
|
|
@@ -48,6 +224,12 @@ export async function generateImage(prompt, options) {
|
|
|
48
224
|
const resolution = (options.resolution || '1K');
|
|
49
225
|
const aspect = (options.aspect || '1:1');
|
|
50
226
|
const refs = options.ref || [];
|
|
227
|
+
const provider = (options.provider || 'gemini');
|
|
228
|
+
// Validate provider
|
|
229
|
+
if (!PROVIDERS.includes(provider)) {
|
|
230
|
+
console.error(chalk.red('Error:') + ` Invalid provider '${provider}'. Use: ${PROVIDERS.join(', ')}`);
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
51
233
|
// Validate resolution
|
|
52
234
|
if (!RESOLUTIONS.includes(resolution)) {
|
|
53
235
|
console.error(chalk.red('Error:') +
|
|
@@ -78,6 +260,11 @@ export async function generateImage(prompt, options) {
|
|
|
78
260
|
}
|
|
79
261
|
// Read prompt
|
|
80
262
|
const promptText = readPrompt(prompt);
|
|
263
|
+
if (provider === 'atlas') {
|
|
264
|
+
console.log(chalk.blue('Generating image with') + ` ${ATLAS_MODEL} (Atlas Cloud)...`);
|
|
265
|
+
await generateViaAtlas(promptText, output, aspect, resolution, refs);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
81
268
|
console.log(chalk.blue('Generating image with') + ` ${MODEL}...`);
|
|
82
269
|
// Create client
|
|
83
270
|
const client = getClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-image.js","sourceRoot":"","sources":["../../src/commands/generate-image.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wCAAwC;AACxC,MAAM,KAAK,GAAG,4BAA4B,CAAC;AAE3C,qBAAqB;AACrB,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAGhD,sBAAsB;AACtB,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAUnF;;GAEG;AACH,SAAS,SAAS;IAChB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACxE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjB,mEAAmE;YACnE,sDAAsD,CACzD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,YAAoB;IACtC,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,wDAAwD;AACxD,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAA6B;IAE7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC;IAC9C,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAe,CAAC;IAC9D,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAgB,CAAC;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;IAE/B,sBAAsB;IACtB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjB,wBAAwB,UAAU,WAAW,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjB,0BAA0B,MAAM,WAAW,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,iCAAiC;IACjC,IAAI,IAAI,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjB,+BAA+B,IAAI,CAAC,MAAM,iBAAiB,oBAAoB,GAAG,CACrF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kCAAkC;IAClC,MAAM,mBAAmB,GAAa,EAAE,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,+BAA+B,GAAG,EAAE,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,cAAc;IACd,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC;IAElE,gBAAgB;IAChB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,sEAAsE;IACtE,IAAI,QAAqF,CAAC;IAE1F,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,UAAU,GAAuE,EAAE,CAAC;QAE1F,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1C,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAChD,qCAAqC;YACrC,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACrD,MAAM,QAAQ,GACZ,GAAG,KAAK,KAAK;gBACX,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,GAAG,KAAK,KAAK;oBACb,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,GAAG,KAAK,MAAM;wBACd,CAAC,CAAC,YAAY;wBACd,CAAC,CAAC,YAAY,CAAC;YAEvB,UAAU,CAAC,IAAI,CAAC;gBACd,UAAU,EAAE;oBACV,QAAQ;oBACR,IAAI,EAAE,UAAU;iBACjB;aACF,CAAC,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5B,QAAQ,GAAG,UAAU,CAAC;QAEtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,mBAAmB,CAAC,MAAM,qBAAqB,CAAC,CAAC;IACzF,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,UAAU,CAAC;IACxB,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAgD;QAC/D,WAAW,EAAE,MAAM;KACpB,CAAC;IACF,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,WAAW,CAAC,SAAS,GAAG,UAAU,CAAC;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;QACnD,KAAK,EAAE,KAAK;QACZ,QAAQ;QACR,MAAM,EAAE;YACN,kBAAkB,EAAE,CAAC,OAAO,CAAC;YAC7B,WAAW;SACZ;KACF,CAAC,CAAC;IAEH,wCAAwC;IACxC,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IACvC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,yBAAyB,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3D,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,IAAI,MAAM,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;IACH,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
1
|
+
{"version":3,"file":"generate-image.js","sourceRoot":"","sources":["../../src/commands/generate-image.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-refresh boundary resolution and task emission (Spec 1470).
|
|
3
|
+
*
|
|
4
|
+
* ## What a boundary is, and why it is recorded rather than inferred
|
|
5
|
+
*
|
|
6
|
+
* A boundary is a moment porch already transitions the state machine, at which a
|
|
7
|
+
* builder's context can be discarded without losing anything: the spec, the plan,
|
|
8
|
+
* `status.yaml`, the thread narrative and git carry the durable state, so a
|
|
9
|
+
* refreshed builder re-orients from disk rather than from memory.
|
|
10
|
+
*
|
|
11
|
+
* The refresh is DESTRUCTIVE — it ends in `/clear`, which has no undo — so it must
|
|
12
|
+
* fire at most once per boundary. Porch transitions can loop: issue #1408 saw
|
|
13
|
+
* verify-approval reset every plan phase back to `pending`, which would replay
|
|
14
|
+
* every plan-phase advance. A side effect that wipes context cannot be guarded by
|
|
15
|
+
* inferring "we must already have done this" from phase or iteration; it has to be
|
|
16
|
+
* a RECORDED FACT. That is what `context_refreshes` in `status.yaml` is.
|
|
17
|
+
*
|
|
18
|
+
* ## Where at-most-once actually comes from
|
|
19
|
+
*
|
|
20
|
+
* Not from a lock or a guard, but from control flow. Each transition site mutates
|
|
21
|
+
* the phase fields AND appends the boundary record in ONE `writeStateAndCommit`,
|
|
22
|
+
* then returns the refresh task INSTEAD of recursing into `next()`. The next
|
|
23
|
+
* `porch next` reads a state where the boundary is already recorded, so
|
|
24
|
+
* {@link hasRefreshed} is true and the normal path runs. There is no window in
|
|
25
|
+
* which the record and the transition disagree, because they are the same write.
|
|
26
|
+
*
|
|
27
|
+
* ## Failure semantics: consumed means consumed
|
|
28
|
+
*
|
|
29
|
+
* The boundary is recorded when the task is EMITTED, not when the refresh
|
|
30
|
+
* succeeds. A refresh that fails, or that the builder never runs, is never
|
|
31
|
+
* retried. That is deliberate:
|
|
32
|
+
*
|
|
33
|
+
* - The builder-side command never writes `status.yaml` (only porch does), so
|
|
34
|
+
* there is no completion signal to model and no way for a failed refresh to
|
|
35
|
+
* corrupt protocol state.
|
|
36
|
+
* - A missed refresh costs context and nothing else. A repeated one costs a
|
|
37
|
+
* builder's working memory, over and over, with nobody watching.
|
|
38
|
+
*
|
|
39
|
+
* Asymmetric costs, so the design fails toward doing nothing.
|
|
40
|
+
*/
|
|
41
|
+
import type { PorchTask, ProjectState, Protocol } from './types.js';
|
|
42
|
+
/**
|
|
43
|
+
* Identifier for entering a protocol phase.
|
|
44
|
+
*
|
|
45
|
+
* Derived from the transition rather than from a configured label, so the record
|
|
46
|
+
* in `status.yaml` cannot drift from the event that produced it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function enterBoundary(phaseId: string): string;
|
|
49
|
+
/** Identifier for advancing INTO a given plan phase. */
|
|
50
|
+
export declare function planPhaseBoundary(planPhaseId: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Is a phase-entry boundary declared for this protocol?
|
|
53
|
+
*
|
|
54
|
+
* Inspects the FIELDS, never the presence of the `context_refresh` object.
|
|
55
|
+
* `context_refresh: {}` is valid and declares nothing, so a truthiness check on
|
|
56
|
+
* the object would report every boundary as declared for a protocol that opted
|
|
57
|
+
* into none of them.
|
|
58
|
+
*/
|
|
59
|
+
export declare function declaresEnter(protocol: Protocol, phaseId: string): boolean;
|
|
60
|
+
/** Is the plan-phase-advance boundary declared for this protocol? */
|
|
61
|
+
export declare function declaresPlanPhaseAdvance(protocol: Protocol): boolean;
|
|
62
|
+
/** Has this boundary already been refreshed for this project? */
|
|
63
|
+
export declare function hasRefreshed(state: ProjectState, boundary: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Record a boundary on the state object.
|
|
66
|
+
*
|
|
67
|
+
* Mutates rather than writing: the caller folds this into the SAME
|
|
68
|
+
* `writeStateAndCommit` as the transition itself, which is what makes the record
|
|
69
|
+
* and the transition atomic. A separate write here would open exactly the window
|
|
70
|
+
* this design closes.
|
|
71
|
+
*/
|
|
72
|
+
export declare function recordRefresh(state: ProjectState, boundary: string, now: string): void;
|
|
73
|
+
/**
|
|
74
|
+
* Mark every recorded boundary as acknowledged, returning true if anything changed.
|
|
75
|
+
*
|
|
76
|
+
* ## Why an acknowledgment exists at all
|
|
77
|
+
*
|
|
78
|
+
* A refresh is unattended, and its worst failure is silent: the builder clears,
|
|
79
|
+
* the re-entry never arrives, and nothing ever says so. The plan's first design
|
|
80
|
+
* tried to DERIVE that from `updated_at` — but the normal task-emission path in
|
|
81
|
+
* `next()` writes no state, so `updated_at` stays pinned at the transition for
|
|
82
|
+
* the whole of a healthy build. A threshold long enough to avoid false positives
|
|
83
|
+
* would be far too long to catch the stall it exists for.
|
|
84
|
+
*
|
|
85
|
+
* So porch records the fact instead. This runs on the first `porch next` that
|
|
86
|
+
* reaches the NORMAL path after a boundary — which only happens if a builder came
|
|
87
|
+
* back and asked for work. A boundary recorded but never acknowledged therefore
|
|
88
|
+
* means exactly one thing: nobody returned.
|
|
89
|
+
*
|
|
90
|
+
* ## Why porch owns it
|
|
91
|
+
*
|
|
92
|
+
* The builder-side command is forbidden from writing `status.yaml`, and that
|
|
93
|
+
* prohibition is load-bearing — it is what makes a failed refresh incapable of
|
|
94
|
+
* corrupting protocol state. So the acknowledgment cannot come from the side that
|
|
95
|
+
* would most naturally report "I'm back"; it has to be inferred by the only
|
|
96
|
+
* writer, from the only evidence it has: the builder asked for its next task.
|
|
97
|
+
*
|
|
98
|
+
* Writes at most once per boundary, so this costs one extra state write per
|
|
99
|
+
* refresh rather than one per `porch next`.
|
|
100
|
+
*
|
|
101
|
+
* ## What this cannot distinguish, and why that is accepted
|
|
102
|
+
*
|
|
103
|
+
* Any normal-path pass acknowledges EVERY outstanding boundary. So a refresh
|
|
104
|
+
* that was refused before clearing — after which the builder simply runs `porch
|
|
105
|
+
* next` — reads as acknowledged, as does a stall a human recovered by hand.
|
|
106
|
+
*
|
|
107
|
+
* That is not a bug to fix here, because porch has exactly one piece of
|
|
108
|
+
* evidence: the builder asked for work. It cannot tell "cleared and came back"
|
|
109
|
+
* from "never cleared" from "was rescued", and inventing a distinction it cannot
|
|
110
|
+
* observe would be worse than admitting the limit. What the signal genuinely
|
|
111
|
+
* means is narrow and still useful: **no builder has asked for work since this
|
|
112
|
+
* boundary was recorded.**
|
|
113
|
+
*/
|
|
114
|
+
export declare function acknowledgeRefreshes(state: ProjectState, now: string): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* How long a refresh may legitimately take before silence means trouble.
|
|
117
|
+
*
|
|
118
|
+
* A refresh is not instant: the builder writes a save (minutes, for a real one),
|
|
119
|
+
* the re-entry is held by Tower for {@link DEFAULT_REENTRY_DELAY_SECONDS}, the
|
|
120
|
+
* mailbox waits for a clean prompt, and only then does the builder run `porch
|
|
121
|
+
* next`. Ten minutes is comfortably past all of that and still far sooner than a
|
|
122
|
+
* human would otherwise notice a builder sitting cleared and idle.
|
|
123
|
+
*/
|
|
124
|
+
export declare const REFRESH_STALL_GRACE_MS: number;
|
|
125
|
+
/**
|
|
126
|
+
* Boundaries recorded but never acknowledged — the raw fact, no timing applied.
|
|
127
|
+
*
|
|
128
|
+
* Use this for HISTORY (what has and has not been acknowledged). For deciding
|
|
129
|
+
* whether to warn a human, use {@link stalledRefreshes}, which adds the grace
|
|
130
|
+
* period.
|
|
131
|
+
*/
|
|
132
|
+
export declare function unacknowledgedRefreshes(state: ProjectState): Array<{
|
|
133
|
+
boundary: string;
|
|
134
|
+
at: string;
|
|
135
|
+
}>;
|
|
136
|
+
/**
|
|
137
|
+
* Unacknowledged boundaries old enough that silence is a problem.
|
|
138
|
+
*
|
|
139
|
+
* ## Why a grace period after all
|
|
140
|
+
*
|
|
141
|
+
* An earlier version of this warned on ANY unacknowledged boundary, with a
|
|
142
|
+
* comment arguing that time-based rules do not work here. That argument
|
|
143
|
+
* conflated two different things, and the result was a warning on every healthy
|
|
144
|
+
* refresh — a false positive during completely normal operation, every single
|
|
145
|
+
* time.
|
|
146
|
+
*
|
|
147
|
+
* What genuinely does not work is deriving the stall from `updated_at`, because
|
|
148
|
+
* that timestamp does not move during a healthy build. But the ACKNOWLEDGMENT
|
|
149
|
+
* does move, exactly when the builder returns. Given a reliable event, a grace
|
|
150
|
+
* period is simply the answer to "has enough time passed that silence is
|
|
151
|
+
* suspicious?" — which is the question, and which the plan asked for in the
|
|
152
|
+
* words "past a threshold".
|
|
153
|
+
*
|
|
154
|
+
* A signal that fires during normal operation is not a signal.
|
|
155
|
+
*/
|
|
156
|
+
export declare function stalledRefreshes(state: ProjectState, now: number, graceMs?: number): Array<{
|
|
157
|
+
boundary: string;
|
|
158
|
+
at: string;
|
|
159
|
+
ageMs: number;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* Should a refresh fire for `boundary`, and is it declared?
|
|
163
|
+
*
|
|
164
|
+
* Deliberately does NOT consider how much context the builder has used. The spec
|
|
165
|
+
* fixes always-fire-at-configured-boundaries over threshold triggering:
|
|
166
|
+
* thresholds would need harness introspection porch does not have, and would make
|
|
167
|
+
* the behavior non-deterministic and untestable. An unnecessary refresh at a
|
|
168
|
+
* clean boundary costs a re-read of artifacts the builder can already see.
|
|
169
|
+
*/
|
|
170
|
+
export declare function shouldRefresh(state: ProjectState, declared: boolean, boundary: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* The single task emitted at a boundary.
|
|
173
|
+
*
|
|
174
|
+
* Deliberately does NOT instruct `porch done`. A refresh is not a build: `porch
|
|
175
|
+
* done` would validate checks and advance the build state, which is wrong at a
|
|
176
|
+
* moment when nothing was built. The builder refreshes and then re-enters through
|
|
177
|
+
* `porch next`, which is also what the post-clear re-entry frame says — so both
|
|
178
|
+
* paths converge on the same next command whether or not the clear lands.
|
|
179
|
+
*/
|
|
180
|
+
export declare function buildRefreshTask(boundary: string): PorchTask;
|
|
181
|
+
//# sourceMappingURL=context-refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-refresh.d.ts","sourceRoot":"","sources":["../../../src/commands/porch/context-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAIH,OAAO,KAAK,EAAwB,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM1F;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D;AAMD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAG1E;AAED,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEpE;AAMD,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAItF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAS9E;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,YAAY,GAClB,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAIzC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,SAAyB,GAC/B,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAOxD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAET;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CA0C5D"}
|