witnora 0.20.7 → 0.20.9
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/cli.js +1 -0
- package/dist/onboard.js +84 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -160,6 +160,7 @@ else if (command === "onboard") {
|
|
|
160
160
|
repository: readFlag("--repo") ?? process.cwd(),
|
|
161
161
|
template: readFlag("--template") ? parseAgentTemplate(readFlag("--template")) : undefined,
|
|
162
162
|
actionTransport: readActionTransport(readFlag("--action-transport")),
|
|
163
|
+
waitForActionPathMs: readActionTransport(readFlag("--action-transport")) && !readBoolFlag("--no-wait-for-action-path") ? 10 * 60 * 1_000 : 0,
|
|
163
164
|
openBrowser: readBoolFlag("--no-browser") ? async () => { } : undefined,
|
|
164
165
|
});
|
|
165
166
|
}
|
package/dist/onboard.js
CHANGED
|
@@ -125,6 +125,7 @@ export async function runOnboard(options) {
|
|
|
125
125
|
let assuranceHarnessChanged = false;
|
|
126
126
|
let httpActionSetup;
|
|
127
127
|
let continuousService;
|
|
128
|
+
let localOutputTaskConfirmed = false;
|
|
128
129
|
const prepareRuntime = async (operation) => {
|
|
129
130
|
const delays = [250, 500, 1_000, 2_000, 4_000, 8_000];
|
|
130
131
|
let lastError;
|
|
@@ -304,7 +305,7 @@ export async function runOnboard(options) {
|
|
|
304
305
|
const runtimeReadiness = doctor.overall === "READY_FOR_RUNTIME" && runtimeBinding
|
|
305
306
|
? { state: "LOCAL_SANDBOX_READY", checkedAt: new Date().toISOString(), limitations: [] }
|
|
306
307
|
: { state: "RECORDED_ONLY", checkedAt: new Date().toISOString(), limitations: [runtimeLimitation ?? "The local sandbox Runtime worker has not established exact adapter, probe, source-key, identity, mandate, and readiness bindings."] };
|
|
307
|
-
|
|
308
|
+
let actionTransportTest = options.actionTransport
|
|
308
309
|
? await runActionTransportTest({
|
|
309
310
|
transport: options.actionTransport,
|
|
310
311
|
repository: repositoryPath,
|
|
@@ -319,12 +320,66 @@ export async function runOnboard(options) {
|
|
|
319
320
|
: undefined;
|
|
320
321
|
const localWorkflowCommand = await detectLocalWorkflowCommand(repositoryPath);
|
|
321
322
|
const cliVersion = await currentCliVersion();
|
|
323
|
+
const agentRunCommand = localWorkflowCommand
|
|
324
|
+
? `npx --yes witnora@${cliVersion} gateway exec -- ${localWorkflowCommand.join(" ")}`
|
|
325
|
+
: undefined;
|
|
322
326
|
await reportInstall(requestFetch, server, token.projectId, token.apiKey, setupPlan.id, {
|
|
323
327
|
status: "verified", attemptId, generatedFiles: relativeGeneratedFiles(repositoryPath, generatedFiles), runtimeReadiness,
|
|
324
328
|
connectedAgent: agentIdentity,
|
|
329
|
+
agentRunCommand,
|
|
325
330
|
...(runtimeBinding ? { runtimeBinding } : {}),
|
|
326
331
|
});
|
|
327
|
-
|
|
332
|
+
if (actionTransportTest?.state === "WAITING_FOR_ACTION_PATH" && (options.waitForActionPathMs ?? 0) > 0) {
|
|
333
|
+
output("\nBase setup is complete. Onboarding is waiting for the Business Task and Action path; it has not claimed completion.\n");
|
|
334
|
+
output(agentRunCommand
|
|
335
|
+
? `Open a second terminal in this repository and run the Agent safely once:\n${agentRunCommand}\n`
|
|
336
|
+
: "Run the Agent normally in its sandbox. If it has no work now, you may enter the workspace and finish Action verification after its first real run.\n");
|
|
337
|
+
output(`Keep this command open for up to ${Math.max(1, Math.ceil((options.waitForActionPathMs ?? 0) / 60_000))} minutes. It will finish automatically after you confirm the Business Task in the browser; no second onboard command is required. Press Ctrl+C to pause safely.\n`);
|
|
338
|
+
const resolution = await waitForOnboardingResolution({
|
|
339
|
+
repository: repositoryPath, server, projectId: token.projectId, apiKey: token.apiKey,
|
|
340
|
+
env: options.env, fetch: requestFetch, sleep: options.sleep, timeoutMs: options.waitForActionPathMs ?? 0,
|
|
341
|
+
});
|
|
342
|
+
if (resolution?.kind === "LOCAL_OUTPUT") {
|
|
343
|
+
localOutputTaskConfirmed = true;
|
|
344
|
+
actionTransportTest = undefined;
|
|
345
|
+
if (assuranceHarnessReadiness.state === "WAITING_FOR_CUSTOMER_HARNESS") {
|
|
346
|
+
assuranceHarnessReadiness = { state: "NOT_REQUIRED_FOR_LOCAL_OUTPUT" };
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
else if (resolution?.kind === "REAL_PATH") {
|
|
350
|
+
const lateActivation = resolution.activation;
|
|
351
|
+
realPathActivation = lateActivation;
|
|
352
|
+
generatedFiles.push(...lateActivation.generatedFiles);
|
|
353
|
+
const harness = await activateManagedWorkflowHarness({ repository: repositoryPath, realPathActivations: lateActivation.activations, previousGeneratedModuleSha256: lateActivation.previousGeneratedModuleSha256 });
|
|
354
|
+
if (harness.created)
|
|
355
|
+
generatedFiles.push(harness.path);
|
|
356
|
+
assuranceHarnessReadiness = { state: "ACTIVE" };
|
|
357
|
+
httpActionSetup = await configureCustomerHttpAction({ repository: repositoryPath, activations: lateActivation.activations });
|
|
358
|
+
generatedFiles.push(...httpActionSetup.generatedFiles);
|
|
359
|
+
if (harness.changed || httpActionSetup.changed) {
|
|
360
|
+
await stopGatewayOwners();
|
|
361
|
+
if (!options.gatewayLifecycle) {
|
|
362
|
+
await installCurrentGatewayService({ repository: repositoryPath, cliEntry: fileURLToPath(new URL("./cli.js", import.meta.url)), configHome: options.configHome });
|
|
363
|
+
managedGateway = await waitForInstalledGatewayService({ repository: repositoryPath, fetch: requestFetch, sleep: options.sleep, timeoutMs: options.timeoutMs });
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
managedGateway = await gatewayLifecycle.start({ repository: repositoryPath, configHome: options.configHome, fetch: requestFetch, output });
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
actionTransportTest = await runActionTransportTest({
|
|
370
|
+
transport: options.actionTransport, repository: repositoryPath, server, projectId: token.projectId, apiKey: token.apiKey,
|
|
371
|
+
repositoryIdentity: repository, httpActionReady: httpActionSetup.state === "READY" && Boolean(httpActionSetup.action),
|
|
372
|
+
fetch: requestFetch, generatedFiles,
|
|
373
|
+
});
|
|
374
|
+
await reportInstall(requestFetch, server, token.projectId, token.apiKey, setupPlan.id, {
|
|
375
|
+
status: "verified", attemptId, generatedFiles: relativeGeneratedFiles(repositoryPath, generatedFiles), runtimeReadiness,
|
|
376
|
+
connectedAgent: agentIdentity, agentRunCommand, ...(runtimeBinding ? { runtimeBinding } : {}),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
output(actionTransportTest?.state === "WAITING_FOR_ACTION_PATH"
|
|
381
|
+
? `\nWitnora base setup completed for ${repository.name}; Action onboarding is paused and still pending.\n`
|
|
382
|
+
: `\nWitnora Setup Autopilot completed for ${repository.name}.\n`);
|
|
328
383
|
output(`Project: ${token.projectId}\nTemplate: ${repository.template} (${repository.kind})\n`);
|
|
329
384
|
output(`Credentials: ${credentialsPath}\nSelf-test receipt: ${receiptPath}\n`);
|
|
330
385
|
output(`Private discovery: ${discovery.capabilityCount} capability group(s); ${discovery.unknownCapabilityCount} pending confirmation.\n`);
|
|
@@ -337,7 +392,9 @@ export async function runOnboard(options) {
|
|
|
337
392
|
: `Runtime: RECORDED_ONLY. ${runtimeReadiness.limitations[0]}\n`);
|
|
338
393
|
output(assuranceHarnessReadiness.state === "ACTIVE"
|
|
339
394
|
? `Assurance Harness: ACTIVE. Nora can dispatch authority-ready Replay and no-write Shadow evaluations without manual Workflow IDs, evaluator origins, credentials, or contract digests.${realPathActivation.activations.length ? ` ${realPathActivation.activations.length} exact sandbox real-path binding(s) passed read-only preflight.` : ""}\n`
|
|
340
|
-
:
|
|
395
|
+
: assuranceHarnessReadiness.state === "NOT_REQUIRED_FOR_LOCAL_OUTPUT"
|
|
396
|
+
? "Assurance Harness: NOT_REQUIRED_FOR_LOCAL_OUTPUT. The approved read-only local-output task is confirmed; no external Action transport is required.\n"
|
|
397
|
+
: `Assurance Harness: WAITING_FOR_CUSTOMER_HARNESS. ${assuranceHarnessReadiness.limitation}\n`);
|
|
341
398
|
if (httpActionSetup?.state === "READY" && httpActionSetup.action) {
|
|
342
399
|
output(`HTTP Action: READY. POST ${managedGateway.baseUrl}${httpActionSetup.action.path}; copy the action-scoped token and request example from .witnora/gateway/HTTP_ACTION.md.\n`);
|
|
343
400
|
}
|
|
@@ -347,11 +404,13 @@ export async function runOnboard(options) {
|
|
|
347
404
|
else if (actionTransportTest) {
|
|
348
405
|
output(`Action transport: ${actionTransportTest.transport.toUpperCase()} is waiting for one exact sandbox Task/action path. ${actionTransportTest.limitation}\n`);
|
|
349
406
|
}
|
|
350
|
-
output(
|
|
351
|
-
?
|
|
352
|
-
:
|
|
407
|
+
output(localOutputTaskConfirmed
|
|
408
|
+
? "Connected. Nora is monitoring this Agent. The approved read-only local-output task is confirmed; no external Action transport is required.\n"
|
|
409
|
+
: actionTransportTest?.state === "WAITING_FOR_ACTION_PATH"
|
|
410
|
+
? `Base Gateway connected, but ${actionTransportTest.transport.toUpperCase()} Action is not verified yet. Run the Agent once and confirm its Business Task in the browser. Recovery only: rerun this command if the original waiting process was closed.\n`
|
|
411
|
+
: "Connected. Nora is monitoring this Agent. Run it normally whenever it is ready; the first source-signed activity will appear automatically without blocking setup.\n");
|
|
353
412
|
output(localWorkflowCommand
|
|
354
|
-
? `Local sandbox command:
|
|
413
|
+
? `Local sandbox command: ${agentRunCommand}\n`
|
|
355
414
|
: `For a local sandbox workflow, use npx --yes witnora@${cliVersion} gateway exec -- <your normal sandbox command> so the Gateway token stays out of shell history.\n`);
|
|
356
415
|
return { projectId: token.projectId, connectionName: token.connectionName, credentialsPath, template: repository.template,
|
|
357
416
|
repositoryKind: repository.kind, generatedFiles, receiptPath, discovery, setupPlanId: setupPlan.id,
|
|
@@ -412,6 +471,24 @@ async function loadMatchingOnboardConnection(options) {
|
|
|
412
471
|
return undefined;
|
|
413
472
|
}
|
|
414
473
|
}
|
|
474
|
+
async function waitForOnboardingResolution(options) {
|
|
475
|
+
const sleep = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
476
|
+
let waited = 0;
|
|
477
|
+
let delay = 2_000;
|
|
478
|
+
while (waited < options.timeoutMs) {
|
|
479
|
+
const activation = await activateRealPathIntegrations(options);
|
|
480
|
+
if (activation.activations.length)
|
|
481
|
+
return { kind: "REAL_PATH", activation };
|
|
482
|
+
const onboarding = await jsonRequest(options.fetch, `${options.server}/v1/projects/${encodeURIComponent(options.projectId)}/onboarding`, { method: "GET", headers: { authorization: `Bearer ${options.apiKey}` } });
|
|
483
|
+
if (onboarding.localOutputTaskConfirmed)
|
|
484
|
+
return { kind: "LOCAL_OUTPUT" };
|
|
485
|
+
const interval = Math.min(delay, options.timeoutMs - waited);
|
|
486
|
+
await sleep(interval);
|
|
487
|
+
waited += interval;
|
|
488
|
+
delay = Math.min(15_000, Math.round(delay * 1.5));
|
|
489
|
+
}
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
415
492
|
async function runActionTransportTest(options) {
|
|
416
493
|
if (!options.httpActionReady)
|
|
417
494
|
return {
|