crewly 1.20.181 → 1.20.183
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/config/roles/orchestrator/prompt.md +4 -0
- package/config/skills/agent/core/report-status/execute.sh +4 -2
- package/dist/backend/backend/src/constants.d.ts +101 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +110 -1
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +22 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +25 -24
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +15 -0
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts +11 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js +44 -9
- package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/runtime-terms.controller.d.ts +31 -0
- package/dist/backend/backend/src/controllers/system/runtime-terms.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/system/runtime-terms.controller.js +99 -0
- package/dist/backend/backend/src/controllers/system/runtime-terms.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +4 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.js +3 -0
- package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js +5 -0
- package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-card.d.ts +14 -4
- package/dist/backend/backend/src/services/decisions/decision-card.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-card.js +31 -10
- package/dist/backend/backend/src/services/decisions/decision-card.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +40 -2
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +100 -8
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.wiring.js +7 -0
- package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts +2 -1
- package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-queue.service.js +6 -3
- package/dist/backend/backend/src/services/messaging/message-queue.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +6 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.d.ts +3 -1
- package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.js +7 -4
- package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-status-router.service.d.ts +110 -0
- package/dist/backend/backend/src/services/orc/orc-status-router.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js +229 -0
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-status-routing.d.ts +108 -0
- package/dist/backend/backend/src/services/orc/orc-status-routing.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-status-routing.js +145 -0
- package/dist/backend/backend/src/services/orc/orc-status-routing.js.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-wake-counter.d.ts +86 -0
- package/dist/backend/backend/src/services/orc/orc-wake-counter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-wake-counter.js +130 -0
- package/dist/backend/backend/src/services/orc/orc-wake-counter.js.map +1 -0
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts +33 -0
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.js +49 -0
- package/dist/backend/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts +2 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js +10 -4
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts +8 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js +5 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +2 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +4 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts +2 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +3 -0
- package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts +15 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.js +13 -2
- package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-driver.d.ts +92 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-driver.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-driver.js +199 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-driver.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-screens.d.ts +79 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-screens.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-screens.js +145 -0
- package/dist/backend/backend/src/services/runtime-terms/antigravity-terms-screens.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/fake-agy-tui.fixture.d.ts +75 -0
- package/dist/backend/backend/src/services/runtime-terms/fake-agy-tui.fixture.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/fake-agy-tui.fixture.js +218 -0
- package/dist/backend/backend/src/services/runtime-terms/fake-agy-tui.fixture.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms-consent.service.d.ts +245 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms-consent.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms-consent.service.js +428 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms-consent.service.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.store.d.ts +67 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.store.js +78 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.store.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.wiring.d.ts +39 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.wiring.js +161 -0
- package/dist/backend/backend/src/services/runtime-terms/runtime-terms.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +16 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +31 -8
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/give-up/give-up-recovery.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/give-up/give-up-recovery.service.js +2 -0
- package/dist/backend/backend/src/services/task-pool/give-up/give-up-recovery.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +23 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +61 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/types/decision.types.d.ts +29 -5
- package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +101 -1
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +110 -1
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js +5 -0
- package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision-card.d.ts +165 -0
- package/dist/cli/backend/src/services/decisions/decision-card.d.ts.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision-card.js +358 -0
- package/dist/cli/backend/src/services/decisions/decision-card.js.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision-contract.d.ts +83 -0
- package/dist/cli/backend/src/services/decisions/decision-contract.d.ts.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision-contract.js +226 -0
- package/dist/cli/backend/src/services/decisions/decision-contract.js.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision-store.d.ts +80 -0
- package/dist/cli/backend/src/services/decisions/decision-store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision-store.js +151 -0
- package/dist/cli/backend/src/services/decisions/decision-store.js.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +376 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js +821 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -0
- package/dist/cli/backend/src/services/decisions/ticket-thread-store.d.ts +97 -0
- package/dist/cli/backend/src/services/decisions/ticket-thread-store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/decisions/ticket-thread-store.js +137 -0
- package/dist/cli/backend/src/services/decisions/ticket-thread-store.js.map +1 -0
- package/dist/cli/backend/src/services/messaging/message-queue.service.d.ts +2 -1
- package/dist/cli/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/message-queue.service.js +6 -3
- package/dist/cli/backend/src/services/messaging/message-queue.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js +6 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts +3 -1
- package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js +7 -4
- package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js.map +1 -1
- package/dist/cli/backend/src/services/orc/orc-status-routing.d.ts +108 -0
- package/dist/cli/backend/src/services/orc/orc-status-routing.d.ts.map +1 -0
- package/dist/cli/backend/src/services/orc/orc-status-routing.js +145 -0
- package/dist/cli/backend/src/services/orc/orc-status-routing.js.map +1 -0
- package/dist/cli/backend/src/services/orc/orc-wake-counter.d.ts +86 -0
- package/dist/cli/backend/src/services/orc/orc-wake-counter.d.ts.map +1 -0
- package/dist/cli/backend/src/services/orc/orc-wake-counter.js +130 -0
- package/dist/cli/backend/src/services/orc/orc-wake-counter.js.map +1 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts +198 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts.map +1 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.js +288 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts +136 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.js +152 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-fallback.types.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts +217 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-smoke-test.service.js +430 -0
- package/dist/cli/backend/src/services/runtime-fallback/runtime-smoke-test.service.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-driver.d.ts +92 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-driver.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-driver.js +199 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-driver.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-screens.d.ts +79 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-screens.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-screens.js +145 -0
- package/dist/cli/backend/src/services/runtime-terms/antigravity-terms-screens.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms-consent.service.d.ts +245 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms-consent.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms-consent.service.js +428 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms-consent.service.js.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms.store.d.ts +67 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms.store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms.store.js +78 -0
- package/dist/cli/backend/src/services/runtime-terms/runtime-terms.store.js.map +1 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +16 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +31 -8
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +23 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +61 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/types/decision.types.d.ts +192 -0
- package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/decision.types.js +13 -0
- package/dist/cli/backend/src/types/decision.types.js.map +1 -0
- package/dist/cli/cli/src/commands/harness-setup.js +2 -2
- package/frontend/dist/assets/{index-4271e95e.js → index-9c91de50.js} +138 -138
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime smoke test — prove a runtime really works on this machine by
|
|
3
|
+
* running one agent on it end to end.
|
|
4
|
+
*
|
|
5
|
+
* Through the backend's own REST API (the calls the dashboard makes):
|
|
6
|
+
*
|
|
7
|
+
* 1. `create_team` — temp project + team `zz-runtime-smoke-<runtime>` with
|
|
8
|
+
* one member on the runtime (a leftover of the same name is removed first).
|
|
9
|
+
* 2. `start_member` — start it (as the owner's dashboard would).
|
|
10
|
+
* 3. `agent_ready` — wait until it registered. Antigravity's first-run Terms
|
|
11
|
+
* screen fails the test with "Antigravity needs its terms accepted once"
|
|
12
|
+
* and the screen text — Crewly never accepts terms for the owner.
|
|
13
|
+
* 4. `send_task` — `echo ok > <file>` with bash, then reply with a token.
|
|
14
|
+
* 5. `bash` — the file holds `ok`.
|
|
15
|
+
* 6. `reply` — the token `SMOKE-ok-<nonce>` shows in the agent's output. The
|
|
16
|
+
* task never contains that string verbatim (only its parts), so an echo
|
|
17
|
+
* of the task does not count.
|
|
18
|
+
* 7. `cleanup` — stop and delete the team and the project (always).
|
|
19
|
+
*
|
|
20
|
+
* Bounded by 5 minutes. specs/2026-10-01-runtime-fallback.md
|
|
21
|
+
*
|
|
22
|
+
* @module services/runtime-fallback/runtime-smoke-test.service
|
|
23
|
+
*/
|
|
24
|
+
import { randomBytes } from 'crypto';
|
|
25
|
+
import * as fs from 'fs';
|
|
26
|
+
import * as os from 'os';
|
|
27
|
+
import * as path from 'path';
|
|
28
|
+
import { ANTIGRAVITY_CONSTANTS, RUNTIME_FALLBACK_CONSTANTS, RUNTIME_TYPES } from '../../constants.js';
|
|
29
|
+
import { normalizeTerminalOutput, redactSecrets } from '../harness/login-rules.js';
|
|
30
|
+
import { deriveMemberSessionName } from '../../utils/member-session-name.utils.js';
|
|
31
|
+
import { KNOWN_RUNTIMES } from './runtime-fallback.types.js';
|
|
32
|
+
const S = RUNTIME_FALLBACK_CONSTANTS.SMOKE;
|
|
33
|
+
/** The failure reason when the runtime stopped on its first-run Terms screen. */
|
|
34
|
+
export const SMOKE_TERMS_ERROR = 'Antigravity needs its terms accepted once';
|
|
35
|
+
/** Agent statuses that mean "registered and ready". */
|
|
36
|
+
const READY_STATUSES = new Set(['active']);
|
|
37
|
+
/**
|
|
38
|
+
* Whether a screen shows Antigravity's first-run (Terms) screens.
|
|
39
|
+
*
|
|
40
|
+
* @param screen - Screen text
|
|
41
|
+
* @returns True when the Terms / onboarding screen is up
|
|
42
|
+
*/
|
|
43
|
+
export function showsAntigravityTerms(screen) {
|
|
44
|
+
// Wrapped lines lose the space at the break: compare without whitespace too.
|
|
45
|
+
const bare = screen.replace(/\s+/g, '');
|
|
46
|
+
return ANTIGRAVITY_CONSTANTS.SCREEN.FIRST_RUN_MARKERS.some((m) => screen.includes(m) || bare.includes(m.replace(/\s+/g, '')));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The task the smoke agent gets.
|
|
50
|
+
*
|
|
51
|
+
* @param file - Proof file to write with bash
|
|
52
|
+
* @param nonce - Code for the reply token
|
|
53
|
+
* @returns Message text (never contains `SMOKE-ok-<nonce>` verbatim)
|
|
54
|
+
*/
|
|
55
|
+
export function buildSmokeTask(file, nonce) {
|
|
56
|
+
return [
|
|
57
|
+
'Crewly runtime smoke test. Do exactly these two steps and nothing else:',
|
|
58
|
+
`1. With your bash / shell tool, run this command: echo ok > ${file}`,
|
|
59
|
+
`2. Reply with one line made of: the word SMOKE, a dash, the text that file now contains, a dash, and the code ${nonce}` +
|
|
60
|
+
' (for code 1234 and file text "hi" the line would be SMOKE-hi-1234). Send it with your reply / report-status skill' +
|
|
61
|
+
' (status done), or as your answer if you have no such skill.',
|
|
62
|
+
].join('\n');
|
|
63
|
+
}
|
|
64
|
+
/** Runs smoke tests and keeps their jobs. */
|
|
65
|
+
export class RuntimeSmokeTestService {
|
|
66
|
+
deps;
|
|
67
|
+
jobs = new Map();
|
|
68
|
+
running = new Map();
|
|
69
|
+
now;
|
|
70
|
+
sleep;
|
|
71
|
+
/**
|
|
72
|
+
* @param deps - Dependencies
|
|
73
|
+
*/
|
|
74
|
+
constructor(deps) {
|
|
75
|
+
this.deps = deps;
|
|
76
|
+
this.now = deps.now ?? (() => Date.now());
|
|
77
|
+
this.sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Start a smoke test (one per runtime at a time).
|
|
81
|
+
*
|
|
82
|
+
* @param runtime - Runtime id
|
|
83
|
+
* @param opts - `ownerInitiated`: the owner pressed Test (a Terms screen then asks again even after "Don't agree")
|
|
84
|
+
* @returns The job and a promise of its result
|
|
85
|
+
* @throws Error for an unknown runtime
|
|
86
|
+
*/
|
|
87
|
+
start(runtime, opts = {}) {
|
|
88
|
+
if (!KNOWN_RUNTIMES.includes(runtime))
|
|
89
|
+
throw new Error(`Unknown runtime: ${runtime}`);
|
|
90
|
+
this.prune();
|
|
91
|
+
const existing = [...this.jobs.values()].find((j) => j.runtime === runtime && j.state === 'running');
|
|
92
|
+
if (existing)
|
|
93
|
+
return { job: existing, done: this.running.get(existing.jobId) };
|
|
94
|
+
const job = { jobId: `smoke-${runtime}-${randomBytes(4).toString('hex')}`, runtime, state: 'running', startedAt: new Date(this.now()).toISOString() };
|
|
95
|
+
this.jobs.set(job.jobId, job);
|
|
96
|
+
const done = this.run(runtime).then((result) => {
|
|
97
|
+
job.state = 'done';
|
|
98
|
+
job.result = result;
|
|
99
|
+
this.running.delete(job.jobId);
|
|
100
|
+
if (result.error === SMOKE_TERMS_ERROR) {
|
|
101
|
+
try {
|
|
102
|
+
this.deps.onTermsScreen?.(runtime, { ownerInitiated: opts.ownerInitiated === true, ...(result.screen ? { screen: result.screen } : {}) });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// reporting only
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
});
|
|
110
|
+
this.running.set(job.jobId, done);
|
|
111
|
+
return { job, done };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A job by id.
|
|
115
|
+
*
|
|
116
|
+
* @param jobId - Job id
|
|
117
|
+
* @returns Job, or null
|
|
118
|
+
*/
|
|
119
|
+
get(jobId) {
|
|
120
|
+
return this.jobs.get(jobId) ?? null;
|
|
121
|
+
}
|
|
122
|
+
prune() {
|
|
123
|
+
for (const [id, job] of this.jobs) {
|
|
124
|
+
if (job.state === 'done' && this.now() - Date.parse(job.startedAt) > S.JOB_TTL_MS)
|
|
125
|
+
this.jobs.delete(id);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Run one smoke test.
|
|
130
|
+
*
|
|
131
|
+
* @param runtime - Runtime id
|
|
132
|
+
* @returns Result (never throws)
|
|
133
|
+
*/
|
|
134
|
+
async run(runtime) {
|
|
135
|
+
const api = this.deps.api;
|
|
136
|
+
const started = this.now();
|
|
137
|
+
const deadline = started + (this.deps.timeoutMs ?? S.TIMEOUT_MS);
|
|
138
|
+
const pollMs = this.deps.pollMs ?? S.POLL_MS;
|
|
139
|
+
const name = `${S.TEAM_PREFIX}${runtime}`;
|
|
140
|
+
const nonce = this.deps.nonce?.() ?? randomBytes(3).toString('hex');
|
|
141
|
+
const workDir = path.join(this.deps.workRoot ?? path.join(os.tmpdir(), 'crewly-runtime-smoke'), `${runtime}-${nonce}`);
|
|
142
|
+
const proofFile = path.join(workDir, `smoke-${nonce}.txt`);
|
|
143
|
+
const token = `SMOKE-ok-${nonce}`;
|
|
144
|
+
const steps = [];
|
|
145
|
+
let teamId = null;
|
|
146
|
+
let projectId = null;
|
|
147
|
+
let sessionName = '';
|
|
148
|
+
let screen = '';
|
|
149
|
+
let stepStart = this.now();
|
|
150
|
+
const pass = (step, detail) => {
|
|
151
|
+
steps.push({ step, ok: true, ms: this.now() - stepStart, ...(detail ? { detail } : {}) });
|
|
152
|
+
stepStart = this.now();
|
|
153
|
+
};
|
|
154
|
+
// The live screen; once the session is gone (a refused start), its log.
|
|
155
|
+
const readScreen = async () => {
|
|
156
|
+
if (!sessionName)
|
|
157
|
+
return screen;
|
|
158
|
+
let text = '';
|
|
159
|
+
try {
|
|
160
|
+
text = await api.capture(sessionName, S.CAPTURE_LINES);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// session gone — fall back to its log
|
|
164
|
+
}
|
|
165
|
+
if (!text)
|
|
166
|
+
text = await api.sessionLog(sessionName, S.CAPTURE_LINES).catch(() => '');
|
|
167
|
+
if (text)
|
|
168
|
+
screen = redactSecrets(normalizeTerminalOutput(text).text);
|
|
169
|
+
return screen;
|
|
170
|
+
};
|
|
171
|
+
let failure = null;
|
|
172
|
+
const fail = (step, error) => {
|
|
173
|
+
failure = { step, error };
|
|
174
|
+
steps.push({ step, ok: false, ms: this.now() - stepStart, detail: error });
|
|
175
|
+
};
|
|
176
|
+
const termsCheck = (text) => runtime === RUNTIME_TYPES.ANTIGRAVITY_CLI && showsAntigravityTerms(text);
|
|
177
|
+
const TERMS = SMOKE_TERMS_ERROR;
|
|
178
|
+
try {
|
|
179
|
+
// 1. Team (and a scratch project so the agent never works in a real one)
|
|
180
|
+
await this.removeLeftovers(name);
|
|
181
|
+
fs.mkdirSync(workDir, { recursive: true });
|
|
182
|
+
projectId = await api.createProject(name, workDir);
|
|
183
|
+
const created = await api.createTeam({
|
|
184
|
+
name,
|
|
185
|
+
description: 'Temporary team for a runtime smoke test (deleted afterwards).',
|
|
186
|
+
projectIds: [projectId],
|
|
187
|
+
members: [
|
|
188
|
+
{
|
|
189
|
+
name: S.MEMBER_NAME,
|
|
190
|
+
role: S.MEMBER_ROLE,
|
|
191
|
+
runtimeType: runtime,
|
|
192
|
+
...(runtime === RUNTIME_TYPES.CREWLY_AGENT
|
|
193
|
+
? { modelId: this.deps.crewlyAgentModel?.() ?? RUNTIME_FALLBACK_CONSTANTS.DEFAULT_CREWLY_AGENT_MODEL }
|
|
194
|
+
: {}),
|
|
195
|
+
systemPrompt: 'You are a smoke-test agent. Do exactly what each message asks and nothing else.',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
});
|
|
199
|
+
teamId = created.id;
|
|
200
|
+
pass('create_team', name);
|
|
201
|
+
// 2. Start
|
|
202
|
+
const startResult = await api.startMember(created.id, created.memberId);
|
|
203
|
+
const member = await api.getMember(created.id, created.memberId).catch(() => null);
|
|
204
|
+
sessionName = member?.sessionName || deriveMemberSessionName(name, S.MEMBER_NAME, created.memberId);
|
|
205
|
+
if (!startResult.ok) {
|
|
206
|
+
const text = await readScreen();
|
|
207
|
+
if (termsCheck(text) || /first-run screens|Terms of Service/i.test(startResult.error ?? ''))
|
|
208
|
+
fail('start_member', TERMS);
|
|
209
|
+
else
|
|
210
|
+
fail('start_member', startResult.error ?? 'The member did not start');
|
|
211
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
212
|
+
}
|
|
213
|
+
pass('start_member');
|
|
214
|
+
// 3. Registered (watch for the Terms screen meanwhile)
|
|
215
|
+
let ready = false;
|
|
216
|
+
while (this.now() < deadline) {
|
|
217
|
+
const m = await api.getMember(created.id, created.memberId).catch(() => null);
|
|
218
|
+
if (m?.sessionName)
|
|
219
|
+
sessionName = m.sessionName;
|
|
220
|
+
if (termsCheck(await readScreen())) {
|
|
221
|
+
fail('agent_ready', TERMS);
|
|
222
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
223
|
+
}
|
|
224
|
+
if (m && READY_STATUSES.has(m.agentStatus)) {
|
|
225
|
+
ready = true;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
await this.sleep(pollMs);
|
|
229
|
+
}
|
|
230
|
+
if (!ready) {
|
|
231
|
+
fail('agent_ready', 'The agent did not register in time');
|
|
232
|
+
await readScreen();
|
|
233
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
234
|
+
}
|
|
235
|
+
pass('agent_ready', sessionName);
|
|
236
|
+
// 4. Task
|
|
237
|
+
const delivered = await api.deliver(sessionName, buildSmokeTask(proofFile, nonce));
|
|
238
|
+
if (!delivered.ok) {
|
|
239
|
+
fail('send_task', delivered.error ?? 'The task could not be delivered');
|
|
240
|
+
await readScreen();
|
|
241
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
242
|
+
}
|
|
243
|
+
pass('send_task');
|
|
244
|
+
// 5. bash ran, 6. reply came back
|
|
245
|
+
let bashOk = false;
|
|
246
|
+
let replied = false;
|
|
247
|
+
while (this.now() < deadline && !(bashOk && replied)) {
|
|
248
|
+
if (!bashOk && readProof(proofFile) === 'ok') {
|
|
249
|
+
bashOk = true;
|
|
250
|
+
pass('bash');
|
|
251
|
+
}
|
|
252
|
+
const text = await readScreen();
|
|
253
|
+
if (termsCheck(text)) {
|
|
254
|
+
fail(bashOk ? 'reply' : 'bash', TERMS);
|
|
255
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
256
|
+
}
|
|
257
|
+
if (!replied && (text.includes(token) || text.replace(/\s+/g, '').includes(token)))
|
|
258
|
+
replied = true;
|
|
259
|
+
if (bashOk && replied)
|
|
260
|
+
break;
|
|
261
|
+
await this.sleep(pollMs);
|
|
262
|
+
}
|
|
263
|
+
if (!bashOk)
|
|
264
|
+
fail('bash', `The agent did not run "echo ok" with bash (no ${path.basename(proofFile)})`);
|
|
265
|
+
else if (!replied)
|
|
266
|
+
fail('reply', `No reply with the token ${token}`);
|
|
267
|
+
else
|
|
268
|
+
pass('reply', token);
|
|
269
|
+
if (failure)
|
|
270
|
+
await readScreen();
|
|
271
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
const step = !teamId ? 'create_team' : !sessionName ? 'start_member' : 'send_task';
|
|
275
|
+
fail(step, err instanceof Error ? err.message : String(err));
|
|
276
|
+
return this.result(runtime, started, steps, failure, screen);
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
stepStart = this.now();
|
|
280
|
+
const cleanupErrors = [];
|
|
281
|
+
if (teamId) {
|
|
282
|
+
await api.stopTeam(teamId).catch((e) => cleanupErrors.push(String(e)));
|
|
283
|
+
await api.deleteTeam(teamId).catch((e) => cleanupErrors.push(String(e)));
|
|
284
|
+
}
|
|
285
|
+
// A start the runtime refused (e.g. Antigravity's first-run screen)
|
|
286
|
+
// leaves a PTY the team no longer knows about.
|
|
287
|
+
if (sessionName && (await api.sessionExists(sessionName).catch(() => false))) {
|
|
288
|
+
await api.killSession(sessionName).catch((e) => cleanupErrors.push(String(e)));
|
|
289
|
+
}
|
|
290
|
+
if (projectId)
|
|
291
|
+
await api.deleteProject(projectId).catch((e) => cleanupErrors.push(String(e)));
|
|
292
|
+
try {
|
|
293
|
+
fs.rmSync(workDir, { recursive: true, force: true });
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// scratch only
|
|
297
|
+
}
|
|
298
|
+
steps.push({ step: 'cleanup', ok: cleanupErrors.length === 0, ms: this.now() - stepStart, ...(cleanupErrors.length ? { detail: cleanupErrors.join('; ') } : {}) });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Remove a team / project left over from an earlier run. */
|
|
302
|
+
async removeLeftovers(name) {
|
|
303
|
+
const api = this.deps.api;
|
|
304
|
+
for (const team of (await api.listTeams().catch(() => [])).filter((t) => t.name === name)) {
|
|
305
|
+
await api.stopTeam(team.id).catch(() => undefined);
|
|
306
|
+
await api.deleteTeam(team.id).catch(() => undefined);
|
|
307
|
+
}
|
|
308
|
+
for (const project of (await api.listProjects().catch(() => [])).filter((p) => p.name === name)) {
|
|
309
|
+
await api.deleteProject(project.id).catch(() => undefined);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
result(runtime, started, steps, failure, screen) {
|
|
313
|
+
const tail = screen.split('\n').slice(-S.SCREEN_LINES).join('\n').trim();
|
|
314
|
+
return {
|
|
315
|
+
runtime,
|
|
316
|
+
passed: failure === null,
|
|
317
|
+
...(failure ? { failedStep: failure.step, error: failure.error } : {}),
|
|
318
|
+
steps,
|
|
319
|
+
...(failure && tail ? { screen: tail } : {}),
|
|
320
|
+
durationMs: this.now() - started,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Read the proof file.
|
|
326
|
+
*
|
|
327
|
+
* @param file - Path
|
|
328
|
+
* @returns Its trimmed text, or null
|
|
329
|
+
*/
|
|
330
|
+
function readProof(file) {
|
|
331
|
+
try {
|
|
332
|
+
return fs.readFileSync(file, 'utf-8').trim();
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/** Fetch-based client for the local API (the default {@link SmokeApi}). */
|
|
339
|
+
export class LocalSmokeApi {
|
|
340
|
+
baseUrl;
|
|
341
|
+
token;
|
|
342
|
+
/**
|
|
343
|
+
* @param baseUrl - e.g. http://127.0.0.1:8787
|
|
344
|
+
* @param token - Crewly API token
|
|
345
|
+
*/
|
|
346
|
+
constructor(baseUrl, token) {
|
|
347
|
+
this.baseUrl = baseUrl;
|
|
348
|
+
this.token = token;
|
|
349
|
+
}
|
|
350
|
+
async call(method, route, body) {
|
|
351
|
+
const res = await fetch(`${this.baseUrl()}/api${route}`, {
|
|
352
|
+
method,
|
|
353
|
+
headers: {
|
|
354
|
+
'content-type': 'application/json',
|
|
355
|
+
'x-crewly-token': this.token(),
|
|
356
|
+
// The owner's dashboard: the wake / commitment gates are for agents.
|
|
357
|
+
'x-crewly-caller': 'dashboard',
|
|
358
|
+
},
|
|
359
|
+
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
|
|
360
|
+
});
|
|
361
|
+
const json = (await res.json().catch(() => ({})));
|
|
362
|
+
if (!res.ok || json.success === false)
|
|
363
|
+
throw new Error(json.error ?? `${method} ${route} → HTTP ${res.status}`);
|
|
364
|
+
return json;
|
|
365
|
+
}
|
|
366
|
+
async listTeams() {
|
|
367
|
+
const r = await this.call('GET', '/teams');
|
|
368
|
+
return r.data ?? [];
|
|
369
|
+
}
|
|
370
|
+
async listProjects() {
|
|
371
|
+
const r = await this.call('GET', '/projects');
|
|
372
|
+
return r.data ?? [];
|
|
373
|
+
}
|
|
374
|
+
async createProject(name, projectPath) {
|
|
375
|
+
const r = await this.call('POST', '/projects', { name, path: projectPath, description: 'Runtime smoke test (temporary)' });
|
|
376
|
+
return r.data.id;
|
|
377
|
+
}
|
|
378
|
+
async deleteProject(projectId) {
|
|
379
|
+
await this.call('DELETE', `/projects/${encodeURIComponent(projectId)}`);
|
|
380
|
+
}
|
|
381
|
+
async createTeam(body) {
|
|
382
|
+
const r = await this.call('POST', '/teams', body);
|
|
383
|
+
return { id: r.data.id, memberId: r.data.members[0].id };
|
|
384
|
+
}
|
|
385
|
+
async startMember(teamId, memberId) {
|
|
386
|
+
try {
|
|
387
|
+
await this.call('POST', `/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(memberId)}/start`, {});
|
|
388
|
+
return { ok: true };
|
|
389
|
+
}
|
|
390
|
+
catch (err) {
|
|
391
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async getMember(teamId, memberId) {
|
|
395
|
+
const r = await this.call('GET', `/teams/${encodeURIComponent(teamId)}`);
|
|
396
|
+
const m = r.data.members.find((x) => x.id === memberId);
|
|
397
|
+
return m ? { agentStatus: m.agentStatus, sessionName: m.sessionName } : null;
|
|
398
|
+
}
|
|
399
|
+
async capture(sessionName, lines) {
|
|
400
|
+
const r = await this.call('GET', `/terminal/${encodeURIComponent(sessionName)}/output?lines=${lines}`);
|
|
401
|
+
return typeof r.data === 'string' ? r.data : r.data?.output ?? '';
|
|
402
|
+
}
|
|
403
|
+
async sessionLog(sessionName, lines) {
|
|
404
|
+
const r = await this.call('GET', `/sessions/${encodeURIComponent(sessionName)}/logs?lines=${lines}`);
|
|
405
|
+
return (r.data?.lines ?? []).join('\n');
|
|
406
|
+
}
|
|
407
|
+
async deliver(sessionName, message) {
|
|
408
|
+
try {
|
|
409
|
+
await this.call('POST', `/terminal/${encodeURIComponent(sessionName)}/deliver`, { message });
|
|
410
|
+
return { ok: true };
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
async killSession(sessionName) {
|
|
417
|
+
await this.call('DELETE', `/terminal/${encodeURIComponent(sessionName)}`);
|
|
418
|
+
}
|
|
419
|
+
async sessionExists(sessionName) {
|
|
420
|
+
const r = await this.call('GET', `/terminal/${encodeURIComponent(sessionName)}/exists`);
|
|
421
|
+
return r.data?.exists === true;
|
|
422
|
+
}
|
|
423
|
+
async stopTeam(teamId) {
|
|
424
|
+
await this.call('POST', `/teams/${encodeURIComponent(teamId)}/stop`, {});
|
|
425
|
+
}
|
|
426
|
+
async deleteTeam(teamId) {
|
|
427
|
+
await this.call('DELETE', `/teams/${encodeURIComponent(teamId)}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
//# sourceMappingURL=runtime-smoke-test.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-smoke-test.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/runtime-smoke-test.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive Antigravity CLI's first-run screens to the owner's choice,
|
|
3
|
+
* deterministically, in a terminal the harness controls.
|
|
4
|
+
*
|
|
5
|
+
* One key at a time; before every key the screen is read and parsed
|
|
6
|
+
* ({@link parseAntigravityTermsScreen}) and the next key is chosen from what
|
|
7
|
+
* is on screen — never from a fixed key count:
|
|
8
|
+
*
|
|
9
|
+
* - colour scheme: bring the focus to `terminal`, Enter; leave "Import
|
|
10
|
+
* extensions from Gemini CLI" unchecked; Enter on Next only when the
|
|
11
|
+
* screen shows `* terminal` and the import box unchecked;
|
|
12
|
+
* - Terms: toggle the data-sharing box only when it differs from the
|
|
13
|
+
* owner's choice, re-read to verify, then go to Done and press Enter —
|
|
14
|
+
* only when the box (read again, right then) matches the choice;
|
|
15
|
+
* - then wait for the main prompt.
|
|
16
|
+
*
|
|
17
|
+
* Anything that does not match (an unknown screen for too long, an account
|
|
18
|
+
* sign-in, no focus, too many keys) aborts: Done is never pressed after a
|
|
19
|
+
* mismatch. specs/2026-10-01-runtime-terms-consent.md
|
|
20
|
+
*
|
|
21
|
+
* @module services/runtime-terms/antigravity-terms-driver
|
|
22
|
+
*/
|
|
23
|
+
import { type AntigravityTermsScreen } from './antigravity-terms-screens.js';
|
|
24
|
+
/** A terminal the driver can type into and read (a PTY session; the fake TUI in tests). */
|
|
25
|
+
export interface TermsTerminal {
|
|
26
|
+
/** Write raw bytes (key escape sequences) */
|
|
27
|
+
write(data: string): void | Promise<void>;
|
|
28
|
+
/** Current screen text */
|
|
29
|
+
capture(): string | Promise<string>;
|
|
30
|
+
}
|
|
31
|
+
/** Keys the driver sends. */
|
|
32
|
+
export type DriverKey = 'Up' | 'Down' | 'Left' | 'Right' | 'Enter';
|
|
33
|
+
/** Their bytes (the same as the session helper's KEY_CODES). */
|
|
34
|
+
export declare const DRIVER_KEY_BYTES: Readonly<Record<DriverKey, string>>;
|
|
35
|
+
/** Outcome of a drive. */
|
|
36
|
+
export interface TermsDriveResult {
|
|
37
|
+
ok: boolean;
|
|
38
|
+
/** Done was pressed (the terms were accepted on screen) */
|
|
39
|
+
donePressed: boolean;
|
|
40
|
+
/** The runtime opened straight to its prompt: terms were already accepted */
|
|
41
|
+
alreadyAccepted: boolean;
|
|
42
|
+
/** Data-sharing box state when Done was pressed */
|
|
43
|
+
dataSharing?: boolean;
|
|
44
|
+
/** Why it stopped (English), when not ok */
|
|
45
|
+
error?: string;
|
|
46
|
+
/** Keys sent, in order */
|
|
47
|
+
keys: DriverKey[];
|
|
48
|
+
/** Last screen text */
|
|
49
|
+
screen: string;
|
|
50
|
+
}
|
|
51
|
+
/** Options. */
|
|
52
|
+
export interface TermsDriveOptions {
|
|
53
|
+
/** Leave the data-sharing box checked */
|
|
54
|
+
shareData: boolean;
|
|
55
|
+
now?: () => number;
|
|
56
|
+
sleep?: (ms: number) => Promise<void>;
|
|
57
|
+
pollMs?: number;
|
|
58
|
+
keySettleMs?: number;
|
|
59
|
+
launchTimeoutMs?: number;
|
|
60
|
+
unknownScreenTimeoutMs?: number;
|
|
61
|
+
promptTimeoutMs?: number;
|
|
62
|
+
maxKeys?: number;
|
|
63
|
+
}
|
|
64
|
+
/** What the next step is. */
|
|
65
|
+
type Step = {
|
|
66
|
+
key: DriverKey;
|
|
67
|
+
} | {
|
|
68
|
+
wait: true;
|
|
69
|
+
} | {
|
|
70
|
+
done: true;
|
|
71
|
+
} | {
|
|
72
|
+
abort: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Decide the next step for a parsed screen.
|
|
76
|
+
*
|
|
77
|
+
* @param s - Parsed screen
|
|
78
|
+
* @param shareData - Owner's choice for the data-sharing box
|
|
79
|
+
* @param donePressed - Done was already pressed
|
|
80
|
+
* @returns Next step
|
|
81
|
+
*/
|
|
82
|
+
export declare function nextTermsStep(s: AntigravityTermsScreen, shareData: boolean, donePressed: boolean): Step;
|
|
83
|
+
/**
|
|
84
|
+
* Drive the first-run screens. Never throws.
|
|
85
|
+
*
|
|
86
|
+
* @param term - Terminal running a freshly launched `agy`
|
|
87
|
+
* @param opts - Owner's choice and timing
|
|
88
|
+
* @returns Result
|
|
89
|
+
*/
|
|
90
|
+
export declare function driveAntigravityTerms(term: TermsTerminal, opts: TermsDriveOptions): Promise<TermsDriveResult>;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=antigravity-terms-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity-terms-driver.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-terms/antigravity-terms-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAK1G,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC7B,6CAA6C;IAC7C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,0BAA0B;IAC1B,OAAO,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpC;AAED,6BAA6B;AAC7B,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnE,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAMhE,CAAC;AAEF,0BAA0B;AAC1B,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAC;IACzB,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,eAAe;AACf,MAAM,WAAW,iBAAiB;IACjC,yCAAyC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6BAA6B;AAC7B,KAAK,IAAI,GAAG;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,sBAAsB,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI,CAuCvG;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4FnH"}
|