agenttwin 0.3.13 → 0.3.14
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/api.js +11 -1
- package/dist/cli.js +113 -18
- package/dist/dashboard/assets/next/static/chunks/app/account/password/{page-aaee6711085b485d.js → page-ebb8ab25df1b808e.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/dashboard/{layout-09cb13657f62384f.js → layout-f7cd10740b90145d.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/dashboard/{page-945c916b24f48675.js → page-a5ad912a1f481008.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/demo/{page-3cba0aab460c8677.js → page-5495d9cb9a3e1431.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/docs/[[...slug]]/{page-9f7b8dca8b973b15.js → page-9130f219b4b02112.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/enterprise/{page-4986698442bddc6b.js → page-b7e323d45eaf4952.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/{layout-09868e53e4f0541f.js → layout-ed5b209cd1b17365.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/login/page-3887863343ffce8c.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/onboarding/{page-af2c4768dc34ec92.js → page-35795509a58cbc9c.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/{page-507229409812cedd.js → page-4d150b91a7a1abcc.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/pricing/page-388c0afb0ac51384.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/signup/page-3887863343ffce8c.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/v2/dashboard/{layout-77a57cd622171076.js → layout-1430f20bea23253f.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/dashboard/page-12a8d96f5c18b411.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/v2/layout-fb241571c2a60362.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/v2/login/page-7ac4be578a219d6e.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/app/v2/onboarding/{page-abfe2f36213848d7.js → page-16d9efad4103fb58.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/{page-df6a34eff716d18e.js → page-1d465878abb57f0f.js} +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/signup/page-7ac4be578a219d6e.js +1 -0
- package/dist/dashboard/assets/next/static/chunks/{webpack-44457f45df749a89.js → webpack-9ed8651d8c2c40a2.js} +1 -1
- package/dist/dashboard/index.html +2 -2
- package/dist/gateway.js +11 -1
- package/package.json +1 -1
- package/dist/dashboard/assets/next/static/chunks/app/login/page-2e29d4b17645c34c.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/pricing/page-c27282cd7bfb0fcf.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/signup/page-2e29d4b17645c34c.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/dashboard/page-df34bcef0394d10d.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/layout-d1d715b5b2dae3cd.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/login/page-4f60d050bf954194.js +0 -1
- package/dist/dashboard/assets/next/static/chunks/app/v2/signup/page-4f60d050bf954194.js +0 -1
- /package/dist/dashboard/assets/next/static/{BbTZs0rKnsmj45peSnlwJ → O8JeB5KAl7-h1hCNIyUY7}/_buildManifest.js +0 -0
- /package/dist/dashboard/assets/next/static/{BbTZs0rKnsmj45peSnlwJ → O8JeB5KAl7-h1hCNIyUY7}/_ssgManifest.js +0 -0
package/dist/api.js
CHANGED
|
@@ -4290,6 +4290,7 @@ async function startGateway(opts) {
|
|
|
4290
4290
|
const passkeyChallenges = {};
|
|
4291
4291
|
const devices = /* @__PURE__ */ new Map();
|
|
4292
4292
|
let hashing = 0;
|
|
4293
|
+
let localOnboardingUntil = 0;
|
|
4293
4294
|
const dummyPassword = randomBytes6(16).toString("hex") + ":" + randomBytes6(64).toString("hex");
|
|
4294
4295
|
const server = createServer2(async (req, res) => {
|
|
4295
4296
|
try {
|
|
@@ -4356,7 +4357,7 @@ async function startGateway(opts) {
|
|
|
4356
4357
|
};
|
|
4357
4358
|
const profile = (a) => ({ accountId: a.id, email: a.identity?.email, name: a.identity?.name ?? a.label, workspace: a.label, organization: a.organization, workspaceProfile: a.workspaceProfile, passwordEnabled: !!a.identity?.passwordHash, passwordSetupAllowed: !a.identity?.passwordHash && !!a.externalIdentities?.some((i) => i.provider === "google") });
|
|
4358
4359
|
if (path2 === "/v1/dev/workspace" && req.method === "GET" && opts.localDevelopment && ["127.0.0.1", "localhost"].includes(opts.host ?? "") && verificationUrl === "http://localhost:3000/onboarding/") {
|
|
4359
|
-
send(res, 200, { schema: "agenttwin/local-workspace-v1", dashboard: verificationUrl });
|
|
4360
|
+
send(res, 200, { schema: "agenttwin/local-workspace-v1", dashboard: verificationUrl, onboarding: localOnboardingUntil > Date.now() });
|
|
4360
4361
|
return;
|
|
4361
4362
|
}
|
|
4362
4363
|
if (path2 === "/v1/auth/providers" && req.method === "GET") {
|
|
@@ -4859,6 +4860,15 @@ async function startGateway(opts) {
|
|
|
4859
4860
|
send(res, 401, { error: "unauthorized" });
|
|
4860
4861
|
return;
|
|
4861
4862
|
}
|
|
4863
|
+
if (path2 === "/v1/dev/workspace" && req.method === "POST" && opts.localDevelopment && ["127.0.0.1", "localhost"].includes(opts.host ?? "") && verificationUrl === "http://localhost:3000/onboarding/") {
|
|
4864
|
+
if (token || !session || origin !== "http://localhost:3000") {
|
|
4865
|
+
send(res, 403, { error: "browser_session_required" });
|
|
4866
|
+
return;
|
|
4867
|
+
}
|
|
4868
|
+
localOnboardingUntil = Date.now() + 10 * 6e4;
|
|
4869
|
+
send(res, 200, { waiting: true });
|
|
4870
|
+
return;
|
|
4871
|
+
}
|
|
4862
4872
|
if (path2 === "/v1/auth/password" && req.method === "POST") {
|
|
4863
4873
|
if (token || !session || !account.identity || !origin || !allowedOrigins.has(origin)) {
|
|
4864
4874
|
send(res, 403, { error: "browser_session_required" });
|
package/dist/cli.js
CHANGED
|
@@ -1929,7 +1929,7 @@ import { join as join34 } from "path";
|
|
|
1929
1929
|
// package.json
|
|
1930
1930
|
var package_default = {
|
|
1931
1931
|
name: "agenttwin",
|
|
1932
|
-
version: "0.3.
|
|
1932
|
+
version: "0.3.14",
|
|
1933
1933
|
description: "Give your agent a test world before it touches the real one.",
|
|
1934
1934
|
keywords: [
|
|
1935
1935
|
"agent",
|
|
@@ -2055,7 +2055,7 @@ async function runSync(cwd) {
|
|
|
2055
2055
|
if (!response.ok) throw new Error(result.error || "Discovery sync failed: " + response.status);
|
|
2056
2056
|
if (git) await writeFile5(join8(cwd, ".agenttwin/git.json"), JSON.stringify(git) + "\n", { mode: 384 });
|
|
2057
2057
|
const receipts = await syncReceipts(cwd, base, token);
|
|
2058
|
-
return { receipts, synced: true, tools: payload.tools.length, workflows: payload.workflows.length, dashboard: "https://agenttwin.si/dashboard/", uploaded: "discovery, Git metadata and run evidence; no application source or credentials" };
|
|
2058
|
+
return { receipts, synced: true, tools: payload.tools.length, workflows: payload.workflows.length, dashboard: base === "http://localhost:8080" ? "http://localhost:3000/dashboard/" : "https://agenttwin.si/dashboard/", uploaded: "discovery, Git metadata and run evidence; no application source or credentials" };
|
|
2059
2059
|
}
|
|
2060
2060
|
|
|
2061
2061
|
// src/commands/prepare.ts
|
|
@@ -9134,6 +9134,7 @@ async function runInit(opts) {
|
|
|
9134
9134
|
if (opts.agent && (opts.dryRun || opts.json)) throw new Error("A coding session requires a writing, interactive init (omit --dry-run and --json).");
|
|
9135
9135
|
setQuiet(opts.json);
|
|
9136
9136
|
const interactive = !opts.json && !opts.yes && !opts.dryRun && (opts.interactive === true || !opts.json && process.stdin.isTTY === true && process.stdout.isTTY === true);
|
|
9137
|
+
const quickInit = interactive && opts.finishAfterSync === true;
|
|
9137
9138
|
const log = (message) => {
|
|
9138
9139
|
if (!message.startsWith("inspect ")) process.stderr.write(`${message}
|
|
9139
9140
|
`);
|
|
@@ -9159,7 +9160,12 @@ async function runInit(opts) {
|
|
|
9159
9160
|
inventory = applyInventoryAnswers(inventory, Object.fromEntries(excludedTools.map((t) => [`tool.exclude:${t.id}`, false])));
|
|
9160
9161
|
if (!opts.json) {
|
|
9161
9162
|
info("");
|
|
9162
|
-
|
|
9163
|
+
if (quickInit) {
|
|
9164
|
+
const integrations = inventory.tools.filter((tool2) => tool2.category === "dependency").length;
|
|
9165
|
+
const gaps = inventory.coverage.sources.filter((source) => source.status !== "ok" && source.status !== "skipped");
|
|
9166
|
+
info(`Detected ${inventory.services.length} applications, ${integrations} referenced integrations and ${inventory.workflows.length} code paths.`);
|
|
9167
|
+
if (gaps.length) warn(`Scan limitations: ${gaps.map((source) => `${source.id}=${source.status}`).join(", ")}`);
|
|
9168
|
+
} else info(renderOverview(inventory));
|
|
9163
9169
|
info("");
|
|
9164
9170
|
}
|
|
9165
9171
|
const decisions = (await readDecisions(opts.cwd))?.items ?? [];
|
|
@@ -9170,14 +9176,14 @@ async function runInit(opts) {
|
|
|
9170
9176
|
const { parseAnswersFile: parseAnswersFile2 } = await Promise.resolve().then(() => (init_answers(), answers_exports));
|
|
9171
9177
|
answers = parseAnswersFile2(readFileSync2(opts.answers, "utf8"));
|
|
9172
9178
|
}
|
|
9173
|
-
if (interactive && questions.length > 0) {
|
|
9179
|
+
if (interactive && !quickInit && questions.length > 0) {
|
|
9174
9180
|
const asked = await askQuestions(questions);
|
|
9175
9181
|
answers = { ...answers, ...asked.answers };
|
|
9176
9182
|
}
|
|
9177
9183
|
answers = { ...stored, ...defaultAnswers(questions), ...answers };
|
|
9178
9184
|
const finalInventory = applyInventoryAnswers(inventory, answers);
|
|
9179
9185
|
const plan = buildPlan(finalInventory);
|
|
9180
|
-
if (interactive) {
|
|
9186
|
+
if (interactive && !quickInit) {
|
|
9181
9187
|
const proceed = await confirm(`Write ${CONFIG_FILENAME}, ENVIRONMENT.md and REPLICATION.md?`);
|
|
9182
9188
|
if (!proceed) {
|
|
9183
9189
|
info("Aborted \u2014 nothing written.");
|
|
@@ -9203,16 +9209,18 @@ async function runInit(opts) {
|
|
|
9203
9209
|
await writeConfig(opts.cwd, config, { force: opts.force });
|
|
9204
9210
|
await writeFile20(join25(opts.cwd, "ENVIRONMENT.md"), renderEnvironment(finalInventory), "utf8");
|
|
9205
9211
|
await writeFile20(join25(opts.cwd, "REPLICATION.md"), renderReplication(finalInventory, plan), "utf8");
|
|
9206
|
-
|
|
9207
|
-
|
|
9212
|
+
if (!quickInit) {
|
|
9213
|
+
reportPath = await writeBrowserReport(opts.cwd, finalInventory, plan);
|
|
9214
|
+
dashboardPath = await writeDashboard(opts.cwd, finalInventory);
|
|
9215
|
+
}
|
|
9208
9216
|
wrote = true;
|
|
9209
9217
|
if (!opts.json) {
|
|
9210
9218
|
info("");
|
|
9211
9219
|
ok2(`Wrote ${CONFIG_FILENAME}`);
|
|
9212
9220
|
ok2("Wrote ENVIRONMENT.md");
|
|
9213
9221
|
ok2("Wrote REPLICATION.md");
|
|
9214
|
-
ok2(`Browser report: ${reportPath}`);
|
|
9215
|
-
ok2(`Dashboard: ${dashboardPath}`);
|
|
9222
|
+
if (reportPath) ok2(`Browser report: ${reportPath}`);
|
|
9223
|
+
if (dashboardPath) ok2(`Dashboard: ${dashboardPath}`);
|
|
9216
9224
|
}
|
|
9217
9225
|
} else if (!opts.json) {
|
|
9218
9226
|
warn("Dry run \u2014 nothing written.");
|
|
@@ -9348,6 +9356,52 @@ async function saveExplorationRegression(cwd, explorationId, trialIndex, id) {
|
|
|
9348
9356
|
|
|
9349
9357
|
// src/commands/control.ts
|
|
9350
9358
|
init_repair_evidence();
|
|
9359
|
+
|
|
9360
|
+
// src/inventory/workflow-picker.ts
|
|
9361
|
+
function workflowRoute(workflow) {
|
|
9362
|
+
const match = (workflow.entrypoint ?? workflow.title).match(/(?:#|^)route:([A-Z]+):(.+)@\d+$/);
|
|
9363
|
+
return match ? { method: match[1], path: match[2] } : void 0;
|
|
9364
|
+
}
|
|
9365
|
+
function workflowLabel(workflow) {
|
|
9366
|
+
const route = workflowRoute(workflow);
|
|
9367
|
+
return route ? `${route.method} ${route.path}` : workflow.title;
|
|
9368
|
+
}
|
|
9369
|
+
function workflowArea(workflow) {
|
|
9370
|
+
const route = workflowRoute(workflow);
|
|
9371
|
+
if (!route) return void 0;
|
|
9372
|
+
const path2 = route.path.toLowerCase();
|
|
9373
|
+
if (/\/(?:internal|admin)(?:\/|$)/.test(path2) || /\/(?:healthz?|readyz|status|evals)(?:\/|$)/.test(path2)) return "Internal and maintenance";
|
|
9374
|
+
if (/\/(?:mail|email|gmail)(?:\/|$)/.test(path2)) return "Email";
|
|
9375
|
+
if (/\/(?:calendar|meetings?|events?)(?:\/|$)/.test(path2)) return "Calendar";
|
|
9376
|
+
if (/\/(?:billing|payments?|subscriptions?|checkout)(?:\/|$)/.test(path2)) return "Payments and billing";
|
|
9377
|
+
if (/\/(?:auth|login|logout|signup|account|me)(?:\/|$)/.test(path2)) return "Accounts and sign-in";
|
|
9378
|
+
if (/\/(?:chat|messages?|conversations?)(?:\/|$)/.test(path2)) return "Chat and messages";
|
|
9379
|
+
if (/\/(?:tasks?|work|reminders?)(?:\/|$)/.test(path2)) return "Tasks and reminders";
|
|
9380
|
+
return "Other application endpoints";
|
|
9381
|
+
}
|
|
9382
|
+
function workflowAreas(workflows) {
|
|
9383
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
9384
|
+
for (const workflow of workflows) {
|
|
9385
|
+
const area = workflowArea(workflow);
|
|
9386
|
+
if (area) grouped.set(area, [...grouped.get(area) ?? [], workflow]);
|
|
9387
|
+
}
|
|
9388
|
+
return [...grouped.entries()].sort(([a], [b]) => Number(a === "Internal and maintenance") - Number(b === "Internal and maintenance") || a.localeCompare(b));
|
|
9389
|
+
}
|
|
9390
|
+
|
|
9391
|
+
// src/runtime/local-workspace.ts
|
|
9392
|
+
async function detectLocalWorkspace(request = fetch) {
|
|
9393
|
+
try {
|
|
9394
|
+
const response = await request("http://localhost:8080/v1/dev/workspace", { redirect: "error", signal: AbortSignal.timeout(700) });
|
|
9395
|
+
if (!response.ok) return null;
|
|
9396
|
+
const data = await response.json();
|
|
9397
|
+
if (data.schema !== "agenttwin/local-workspace-v1" || data.dashboard !== "http://localhost:3000/onboarding/") return null;
|
|
9398
|
+
return { api: "http://localhost:8080", dashboard: data.dashboard, onboarding: data.onboarding === true };
|
|
9399
|
+
} catch {
|
|
9400
|
+
return null;
|
|
9401
|
+
}
|
|
9402
|
+
}
|
|
9403
|
+
|
|
9404
|
+
// src/commands/control.ts
|
|
9351
9405
|
var CONTROL_ACTIONS = [
|
|
9352
9406
|
"Review service coverage and provider contracts",
|
|
9353
9407
|
"Prepare or select your reviewed workflow world",
|
|
@@ -9377,6 +9431,11 @@ async function runControl(opts) {
|
|
|
9377
9431
|
const wrote = await runInit({ ...opts, interactive, controller: true });
|
|
9378
9432
|
if (!interactive || !wrote) return;
|
|
9379
9433
|
const state = await readState(opts.cwd);
|
|
9434
|
+
const originalApi = process.env.AGENTTWIN_API_URL;
|
|
9435
|
+
if (!originalApi && !process.env.AGENTTWIN_TOKEN) {
|
|
9436
|
+
const local = await detectLocalWorkspace();
|
|
9437
|
+
if (local?.onboarding) process.env.AGENTTWIN_API_URL = local.api;
|
|
9438
|
+
}
|
|
9380
9439
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
9381
9440
|
const log = (message) => process.stdout.write(message + "\n");
|
|
9382
9441
|
const ask = async (prompt) => (await rl.question(prompt + " ")).trim();
|
|
@@ -9400,9 +9459,32 @@ async function runControl(opts) {
|
|
|
9400
9459
|
log("No workflow candidates found. Refresh discovery in Advanced options, or load an existing test file.");
|
|
9401
9460
|
return;
|
|
9402
9461
|
}
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9462
|
+
const areas = workflowAreas(workflows);
|
|
9463
|
+
let matches2 = workflows;
|
|
9464
|
+
if (areas.length) {
|
|
9465
|
+
log("\nWhich part of your application do you want to test?");
|
|
9466
|
+
areas.forEach(([name, items], i) => log(` ${i + 1}. ${name} (${items.length} endpoints)`));
|
|
9467
|
+
log(" a. All code paths, including helpers");
|
|
9468
|
+
log(" 0. Back");
|
|
9469
|
+
const area = await ask("Choose an area, or type a search:");
|
|
9470
|
+
if (!area || area === "0") return;
|
|
9471
|
+
const selectedArea = /^\d+$/.test(area) ? areas[Number(area) - 1] : void 0;
|
|
9472
|
+
if (selectedArea) {
|
|
9473
|
+
matches2 = selectedArea[1];
|
|
9474
|
+
log(`
|
|
9475
|
+
${selectedArea[0]} \u2014 choose an endpoint to prepare. These have not been tested yet.`);
|
|
9476
|
+
} else if (area.toLowerCase() !== "a") {
|
|
9477
|
+
if (/^\d+$/.test(area)) {
|
|
9478
|
+
log("Choose a listed area.");
|
|
9479
|
+
return;
|
|
9480
|
+
}
|
|
9481
|
+
matches2 = workflows.filter((w) => `${w.title} ${w.entrypoint ?? ""}`.toLowerCase().includes(area.toLowerCase()));
|
|
9482
|
+
}
|
|
9483
|
+
} else {
|
|
9484
|
+
log(`${workflows.length} code paths found. These have not been tested yet.`);
|
|
9485
|
+
const query = (await ask("Find a workflow (for example mail, calendar or billing; Enter shows all):")).toLowerCase();
|
|
9486
|
+
matches2 = workflows.filter((w) => `${w.title} ${w.entrypoint ?? ""}`.toLowerCase().includes(query));
|
|
9487
|
+
}
|
|
9406
9488
|
if (!matches2.length) {
|
|
9407
9489
|
log("No matching workflows. Try another search.");
|
|
9408
9490
|
return;
|
|
@@ -9410,7 +9492,7 @@ async function runControl(opts) {
|
|
|
9410
9492
|
let offset = 0;
|
|
9411
9493
|
while (true) {
|
|
9412
9494
|
const page2 = matches2.slice(offset, offset + 10);
|
|
9413
|
-
page2.forEach((w, i) => log(` ${i + 1}. ${w
|
|
9495
|
+
page2.forEach((w, i) => log(` ${i + 1}. ${workflowLabel(w)}`));
|
|
9414
9496
|
log(`Showing ${offset + 1}\u2013${offset + page2.length} of ${matches2.length}. n: next page \xB7 p: previous page \xB7 0: back`);
|
|
9415
9497
|
const selected = await ask("Choose a workflow [0]:");
|
|
9416
9498
|
if (!selected || selected === "0") return;
|
|
@@ -9428,12 +9510,13 @@ async function runControl(opts) {
|
|
|
9428
9510
|
continue;
|
|
9429
9511
|
}
|
|
9430
9512
|
state.workflowId = workflow.id;
|
|
9431
|
-
state.workflowTitle = workflow
|
|
9513
|
+
state.workflowTitle = workflowLabel(workflow);
|
|
9432
9514
|
delete state.world;
|
|
9433
9515
|
delete state.exploration;
|
|
9434
9516
|
delete state.receipt;
|
|
9435
9517
|
await save();
|
|
9436
|
-
log(`Selected: ${workflow
|
|
9518
|
+
log(`Selected: ${workflowLabel(workflow)}`);
|
|
9519
|
+
if (workflow.entrypoint) log(`Source: ${workflow.entrypoint}`);
|
|
9437
9520
|
log("Next: prepare its test. AgentTwin cannot yet turn every detected code path into a runnable test automatically.");
|
|
9438
9521
|
log("Give your coding agent this request:");
|
|
9439
9522
|
log(`Read .agenttwin/AGENT-TASK.md and .agenttwin/inventory.json. Prepare workflow ${JSON.stringify(workflow.id)} (${JSON.stringify(workflow.title)}) as agenttwin.world.json, with bundled application files, supported service operations, synthetic records and reviewed expected outcomes. Report unsupported dependencies; do not replace the application with a demo.`);
|
|
@@ -9444,8 +9527,17 @@ async function runControl(opts) {
|
|
|
9444
9527
|
try {
|
|
9445
9528
|
try {
|
|
9446
9529
|
await connectAndShare();
|
|
9530
|
+
if (opts.finishAfterSync) {
|
|
9531
|
+
log("Setup complete. Project synced; your onboarding page updates automatically. Continue in your browser.");
|
|
9532
|
+
log("For terminal testing later, run npx agenttwin.");
|
|
9533
|
+
return;
|
|
9534
|
+
}
|
|
9447
9535
|
} catch (error) {
|
|
9448
|
-
log(`Connection stopped: ${error instanceof Error ? error.message : String(error)}. Local discovery is saved.
|
|
9536
|
+
log(`Connection stopped: ${error instanceof Error ? error.message : String(error)}. Local discovery is saved. Run npx agenttwin init to retry.`);
|
|
9537
|
+
if (opts.finishAfterSync) {
|
|
9538
|
+
process.exitCode = 1;
|
|
9539
|
+
return;
|
|
9540
|
+
}
|
|
9449
9541
|
}
|
|
9450
9542
|
while (true) {
|
|
9451
9543
|
log(`
|
|
@@ -9610,6 +9702,8 @@ AgentTwin \xB7 ${basename4(opts.cwd)}`);
|
|
|
9610
9702
|
}
|
|
9611
9703
|
} finally {
|
|
9612
9704
|
rl.close();
|
|
9705
|
+
if (originalApi === void 0) delete process.env.AGENTTWIN_API_URL;
|
|
9706
|
+
else process.env.AGENTTWIN_API_URL = originalApi;
|
|
9613
9707
|
}
|
|
9614
9708
|
}
|
|
9615
9709
|
|
|
@@ -10936,7 +11030,7 @@ function helpText() {
|
|
|
10936
11030
|
` ${"services".padEnd(12)}list | coverage | confirm --host HOST --decision include|exclude`,
|
|
10937
11031
|
` ${"example".padEnd(12)}Write an editable multi-service workflow (--out directory)`,
|
|
10938
11032
|
` ${"sync".padEnd(12)}Sync discovery, Git metadata and CLI test results to your dashboard`,
|
|
10939
|
-
` ${"init".padEnd(12)}Discover and
|
|
11033
|
+
` ${"init".padEnd(12)}Discover, connect and sync; continue in your browser`,
|
|
10940
11034
|
` ${"refresh".padEnd(12)}Update discovery without executing application code`,
|
|
10941
11035
|
` ${"discover".padEnd(12)}Build the company inventory (writes .agenttwin/inventory.json)`,
|
|
10942
11036
|
` ${"decide".padEnd(12)}Apply structured decisions (--file or --stdin)`,
|
|
@@ -11249,7 +11343,8 @@ ${result.uploaded}`);
|
|
|
11249
11343
|
agent: str2("agent"),
|
|
11250
11344
|
sync: flag("sync"),
|
|
11251
11345
|
exclude: arr("exclude"),
|
|
11252
|
-
controller: true
|
|
11346
|
+
controller: true,
|
|
11347
|
+
finishAfterSync: positionals[0] === "init"
|
|
11253
11348
|
});
|
|
11254
11349
|
return;
|
|
11255
11350
|
case "logout": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9842],{6419:(e,a,s)=>{"use strict";s.d(a,{default:()=>o});var n=s(1778),t=s(5226),r=s(650);function o(){let[e,a]=(0,t.useState)(null),[s,o]=(0,t.useState)(!0),[i,l]=(0,t.useState)(""),[d,c]=(0,t.useState)(""),[h,u]=(0,t.useState)(!1),[p,w]=(0,t.useState)(""),[g,m]=(0,t.useState)(!1),[f,y]=(0,t.useState)("/login/");async function j(e){if(e.preventDefault(),!h){if(w(""),i!==d)return void w("The passwords do not match.");u(!0);try{let e=await fetch(r.n+"/v1/auth/password",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:i}),signal:AbortSignal.timeout(2e4)}),s=await e.json();if(!e.ok)throw Error(s.error||"Could not create your password.");a(s.user),l(""),c(""),m(!0)}catch(e){w(e instanceof TypeError?"Could not connect to AgentTwin. Please try again.":e instanceof Error?e.message:"Could not create your password.")}finally{u(!1)}}}return(0,t.useEffect)(()=>{let e=new AbortController,s=["localhost","127.0.0.1"].includes(location.hostname)&&"https://api.agenttwin.si"===r.n;return s&&y("https://agenttwin.si/login/"),fetch(r.n+"/v1/auth/me",{credentials:"include",signal:e.signal,cache:"no-store"}).then(async e=>{var s;if(!e.ok)throw Error("Sign in with Google, then open Settings → Email and password.");let n=await e.json();if(!(null==(s=n.user)?void 0:s.email))throw Error("Could not load your account. Please sign in again.");a(n.user)}).catch(a=>{e.signal.aborted||w(a instanceof TypeError?s?"This local preview cannot connect to production sign-in. Open agenttwin.si to manage your password.":"Could not connect to AgentTwin. Please try again.":a instanceof Error?a.message:"Could not load your account.")}).finally(()=>{e.signal.aborted||o(!1)}),()=>e.abort()},[]),(0,n.jsxs)("main",{className:"auth-page auth-entry vercel-auth vercel-entry",children:[(0,n.jsxs)("header",{className:"auth-header",children:[(0,n.jsx)("a",{className:"auth-brand",href:"/","aria-label":"AgentTwin home",children:(0,n.jsx)("img",{src:"assets/logo/mark-twin-rings.svg",width:"26",height:"26",alt:""})}),(0,n.jsx)("a",{className:"auth-header-link",href:"/dashboard/#settings",children:"Back to settings"})]}),(0,n.jsxs)("section",{className:"auth-card auth-entry-card","aria-labelledby":"password-title",children:[(0,n.jsx)("h1",{id:"password-title",children:"Email and password"}),s&&(0,n.jsx)("p",{role:"status",children:"Loading your sign-in methods…"}),p&&(0,n.jsx)("p",{role:"alert",children:p}),g?(0,n.jsxs)("p",{role:"status",children:["Password created. You can now sign in with ",null==e?void 0:e.email," and your password, or continue with Google. Your workspace is the same."]}):(null==e?void 0:e.passwordEnabled)?(0,n.jsxs)("p",{children:["Email and password sign-in is already enabled for ",e.email,"."]}):(null==e?void 0:e.passwordSetupAllowed)?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("p",{children:["Create an AgentTwin password for ",e.email,". Google sign-in will keep working."]}),(0,n.jsx)("p",{children:"For security, sign in with Google within the last 10 minutes before saving."}),(0,n.jsxs)("form",{onSubmit:j,"aria-busy":h,children:[(0,n.jsx)("input",{type:"text",name:"username",autoComplete:"username",value:e.email,readOnly:!0,hidden:!0}),(0,n.jsxs)("label",{htmlFor:"new-password",children:["New password",(0,n.jsx)("input",{id:"new-password",type:"password",autoComplete:"new-password",minLength:12,maxLength:128,required:!0,value:i,onChange:e=>l(e.target.value),"aria-describedby":"password-guidance"})]}),(0,n.jsx)("small",{id:"password-guidance",children:"Use 12–128 characters. This is a new AgentTwin password, separate from your Google password."}),(0,n.jsxs)("label",{htmlFor:"confirm-password",children:["Confirm password",(0,n.jsx)("input",{id:"confirm-password",type:"password",autoComplete:"new-password",minLength:12,maxLength:128,required:!0,value:d,onChange:e=>c(e.target.value)})]}),(0,n.jsx)("button",{className:"auth-primary",type:"submit",disabled:h,children:h?"Saving…":"Create password"})]})]}):e&&(0,n.jsx)("p",{children:"Password setup is available for accounts created with Google."}),!s&&!g&&!(null==e?void 0:e.passwordEnabled)&&(0,n.jsx)("p",{children:(0,n.jsx)("a",{href:f,children:"Sign in with Google again →"})})]}),(0,n.jsx)("footer",{className:"auth-footer",children:(0,n.jsx)("a",{href:"/dashboard/#settings",children:"Back to settings"})})]})}},
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9842],{6419:(e,a,s)=>{"use strict";s.d(a,{default:()=>o});var n=s(1778),t=s(5226),r=s(650);function o(){let[e,a]=(0,t.useState)(null),[s,o]=(0,t.useState)(!0),[i,l]=(0,t.useState)(""),[d,c]=(0,t.useState)(""),[h,u]=(0,t.useState)(!1),[p,w]=(0,t.useState)(""),[g,m]=(0,t.useState)(!1),[f,y]=(0,t.useState)("/login/");async function j(e){if(e.preventDefault(),!h){if(w(""),i!==d)return void w("The passwords do not match.");u(!0);try{let e=await fetch(r.n+"/v1/auth/password",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:i}),signal:AbortSignal.timeout(2e4)}),s=await e.json();if(!e.ok)throw Error(s.error||"Could not create your password.");a(s.user),l(""),c(""),m(!0)}catch(e){w(e instanceof TypeError?"Could not connect to AgentTwin. Please try again.":e instanceof Error?e.message:"Could not create your password.")}finally{u(!1)}}}return(0,t.useEffect)(()=>{let e=new AbortController,s=["localhost","127.0.0.1"].includes(location.hostname)&&"https://api.agenttwin.si"===r.n;return s&&y("https://agenttwin.si/login/"),fetch(r.n+"/v1/auth/me",{credentials:"include",signal:e.signal,cache:"no-store"}).then(async e=>{var s;if(!e.ok)throw Error("Sign in with Google, then open Settings → Email and password.");let n=await e.json();if(!(null==(s=n.user)?void 0:s.email))throw Error("Could not load your account. Please sign in again.");a(n.user)}).catch(a=>{e.signal.aborted||w(a instanceof TypeError?s?"This local preview cannot connect to production sign-in. Open agenttwin.si to manage your password.":"Could not connect to AgentTwin. Please try again.":a instanceof Error?a.message:"Could not load your account.")}).finally(()=>{e.signal.aborted||o(!1)}),()=>e.abort()},[]),(0,n.jsxs)("main",{className:"auth-page auth-entry vercel-auth vercel-entry",children:[(0,n.jsxs)("header",{className:"auth-header",children:[(0,n.jsx)("a",{className:"auth-brand",href:"/","aria-label":"AgentTwin home",children:(0,n.jsx)("img",{src:"assets/logo/mark-twin-rings.svg",width:"26",height:"26",alt:""})}),(0,n.jsx)("a",{className:"auth-header-link",href:"/dashboard/#settings",children:"Back to settings"})]}),(0,n.jsxs)("section",{className:"auth-card auth-entry-card","aria-labelledby":"password-title",children:[(0,n.jsx)("h1",{id:"password-title",children:"Email and password"}),s&&(0,n.jsx)("p",{role:"status",children:"Loading your sign-in methods…"}),p&&(0,n.jsx)("p",{role:"alert",children:p}),g?(0,n.jsxs)("p",{role:"status",children:["Password created. You can now sign in with ",null==e?void 0:e.email," and your password, or continue with Google. Your workspace is the same."]}):(null==e?void 0:e.passwordEnabled)?(0,n.jsxs)("p",{children:["Email and password sign-in is already enabled for ",e.email,"."]}):(null==e?void 0:e.passwordSetupAllowed)?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("p",{children:["Create an AgentTwin password for ",e.email,". Google sign-in will keep working."]}),(0,n.jsx)("p",{children:"For security, sign in with Google within the last 10 minutes before saving."}),(0,n.jsxs)("form",{onSubmit:j,"aria-busy":h,children:[(0,n.jsx)("input",{type:"text",name:"username",autoComplete:"username",value:e.email,readOnly:!0,hidden:!0}),(0,n.jsxs)("label",{htmlFor:"new-password",children:["New password",(0,n.jsx)("input",{id:"new-password",type:"password",autoComplete:"new-password",minLength:12,maxLength:128,required:!0,value:i,onChange:e=>l(e.target.value),"aria-describedby":"password-guidance"})]}),(0,n.jsx)("small",{id:"password-guidance",children:"Use 12–128 characters. This is a new AgentTwin password, separate from your Google password."}),(0,n.jsxs)("label",{htmlFor:"confirm-password",children:["Confirm password",(0,n.jsx)("input",{id:"confirm-password",type:"password",autoComplete:"new-password",minLength:12,maxLength:128,required:!0,value:d,onChange:e=>c(e.target.value)})]}),(0,n.jsx)("button",{className:"auth-primary",type:"submit",disabled:h,children:h?"Saving…":"Create password"})]})]}):e&&(0,n.jsx)("p",{children:"Password setup is available for accounts created with Google."}),!s&&!g&&!(null==e?void 0:e.passwordEnabled)&&(0,n.jsx)("p",{children:(0,n.jsx)("a",{href:f,children:"Sign in with Google again →"})})]}),(0,n.jsx)("footer",{className:"auth-footer",children:(0,n.jsx)("a",{href:"/dashboard/#settings",children:"Back to settings"})})]})}},7461:(e,a,s)=>{Promise.resolve().then(s.bind(s,6419))}},e=>{e.O(0,[1839,650,7903,4816,7358],()=>e(e.s=7461)),_N_E=e.O()}]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1954],{1059:()=>{},1125:()=>{},1127:()=>{},1470:()=>{},1685:()=>{},2569:()=>{},2908:()=>{},
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1954],{1059:()=>{},1125:()=>{},1127:()=>{},1470:()=>{},1685:()=>{},2569:()=>{},2908:()=>{},4389:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,1059,23)),Promise.resolve().then(n.t.bind(n,2569,23)),Promise.resolve().then(n.t.bind(n,1470,23)),Promise.resolve().then(n.t.bind(n,8866,23)),Promise.resolve().then(n.t.bind(n,1685,23)),Promise.resolve().then(n.t.bind(n,1127,23)),Promise.resolve().then(n.t.bind(n,2908,23)),Promise.resolve().then(n.t.bind(n,1125,23))},8866:()=>{}},e=>{e.O(0,[8605,4469,508,7903,4816,7358],()=>e(e.s=4389)),_N_E=e.O()}]);
|