@useorgx/wizard 0.1.24 → 0.1.25
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/README.md +1 -0
- package/dist/cli.js +173 -38
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,6 +61,7 @@ The wizard modifies local tool configuration only. Depending on the command, it
|
|
|
61
61
|
|
|
62
62
|
- `wizard setup` now opens a guided workspace picker in interactive shells, letting you keep the current default workspace, promote another existing workspace, or create a new one and make it active immediately.
|
|
63
63
|
- If the selected workspace has no remembered setup initiative, `wizard setup` offers to create a first initiative, defaulting to `Make OrgX useful on this machine`. It then creates the onboarding workstream and starter task inside that initiative so setup ends with a concrete next action instead of a blank workspace.
|
|
64
|
+
- Repeated setup runs are intentionally quiet. Daily Brief can be configured with defaults, customized, or skipped; skips for Daily Brief, first initiative creation, onboarding task creation, agent roster setup, and the first intent prompt are remembered per workspace so the wizard does not ask again on every run.
|
|
64
65
|
- After the first initiative is ready, setup prints the `/live/<initiative>` URL and a copyable prompt for the user's configured AI tool: continue the initiative, show the next action, and start with the onboarding task.
|
|
65
66
|
- `wizard workspace current` reads the current OrgX workspace from `GET /api/v1/workspaces/current`, with a fallback to workspace listing if that route is unavailable.
|
|
66
67
|
- `wizard workspace list` lists all accessible workspaces.
|
package/dist/cli.js
CHANGED
|
@@ -1375,6 +1375,42 @@ function parseDailyBriefOnboarding(value) {
|
|
|
1375
1375
|
entries
|
|
1376
1376
|
};
|
|
1377
1377
|
}
|
|
1378
|
+
function isSetupPromptKey(value) {
|
|
1379
|
+
return value === "first_initiative" || value === "onboarding_task" || value === "agent_roster" || value === "setup_intent";
|
|
1380
|
+
}
|
|
1381
|
+
function parseSetupPromptDecisionEntry(value) {
|
|
1382
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1383
|
+
return void 0;
|
|
1384
|
+
}
|
|
1385
|
+
const record = value;
|
|
1386
|
+
if (!isNonEmptyString2(record.workspaceId) || !isSetupPromptKey(record.promptKey) || record.status !== "skipped" || !isNonEmptyString2(record.skippedAt)) {
|
|
1387
|
+
return void 0;
|
|
1388
|
+
}
|
|
1389
|
+
return {
|
|
1390
|
+
promptKey: record.promptKey,
|
|
1391
|
+
skippedAt: record.skippedAt.trim(),
|
|
1392
|
+
status: "skipped",
|
|
1393
|
+
workspaceId: record.workspaceId.trim(),
|
|
1394
|
+
...isNonEmptyString2(record.workspaceName) ? { workspaceName: record.workspaceName.trim() } : {}
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
function parseSetupPromptDecisions(value) {
|
|
1398
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1399
|
+
return void 0;
|
|
1400
|
+
}
|
|
1401
|
+
const record = value;
|
|
1402
|
+
if (!isNonEmptyString2(record.updatedAt) || !Array.isArray(record.entries)) {
|
|
1403
|
+
return void 0;
|
|
1404
|
+
}
|
|
1405
|
+
const entries = record.entries.map((entry) => parseSetupPromptDecisionEntry(entry)).filter(
|
|
1406
|
+
(entry) => Boolean(entry)
|
|
1407
|
+
);
|
|
1408
|
+
if (entries.length === 0) return void 0;
|
|
1409
|
+
return {
|
|
1410
|
+
updatedAt: record.updatedAt.trim(),
|
|
1411
|
+
entries
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1378
1414
|
function createWizardState(now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
1379
1415
|
return {
|
|
1380
1416
|
installationId: `wizard-${randomUUID()}`,
|
|
@@ -1391,6 +1427,7 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1391
1427
|
const skillFiles = parseSkillFiles(record.skillFiles);
|
|
1392
1428
|
const peopleFirstCapture = parsePeopleFirstCapture(record.peopleFirstCapture);
|
|
1393
1429
|
const dailyBriefOnboarding = parseDailyBriefOnboarding(record.dailyBriefOnboarding);
|
|
1430
|
+
const setupPromptDecisions = parseSetupPromptDecisions(record.setupPromptDecisions);
|
|
1394
1431
|
return {
|
|
1395
1432
|
installationId: record.installationId.trim(),
|
|
1396
1433
|
createdAt: record.createdAt.trim(),
|
|
@@ -1402,7 +1439,8 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1402
1439
|
...onboardingTask ? { onboardingTask } : {},
|
|
1403
1440
|
...skillFiles ? { skillFiles } : {},
|
|
1404
1441
|
...peopleFirstCapture ? { peopleFirstCapture } : {},
|
|
1405
|
-
...dailyBriefOnboarding ? { dailyBriefOnboarding } : {}
|
|
1442
|
+
...dailyBriefOnboarding ? { dailyBriefOnboarding } : {},
|
|
1443
|
+
...setupPromptDecisions ? { setupPromptDecisions } : {}
|
|
1406
1444
|
};
|
|
1407
1445
|
}
|
|
1408
1446
|
function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
@@ -1435,6 +1473,10 @@ function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
|
1435
1473
|
if (dailyBriefOnboarding !== void 0) {
|
|
1436
1474
|
state.dailyBriefOnboarding = dailyBriefOnboarding;
|
|
1437
1475
|
}
|
|
1476
|
+
const setupPromptDecisions = parseSetupPromptDecisions(parsed.setupPromptDecisions);
|
|
1477
|
+
if (setupPromptDecisions !== void 0) {
|
|
1478
|
+
state.setupPromptDecisions = setupPromptDecisions;
|
|
1479
|
+
}
|
|
1438
1480
|
return state;
|
|
1439
1481
|
}
|
|
1440
1482
|
function getDailyBriefOnboardingDecision(workspaceId, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
@@ -1458,6 +1500,39 @@ function recordDailyBriefOnboardingDecision(entry, statePath = ORGX_WIZARD_STATE
|
|
|
1458
1500
|
};
|
|
1459
1501
|
}, statePath);
|
|
1460
1502
|
}
|
|
1503
|
+
function getSetupPromptDecision(workspaceId, promptKey, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1504
|
+
const state = readWizardState(statePath);
|
|
1505
|
+
return state?.setupPromptDecisions?.entries.find(
|
|
1506
|
+
(entry) => entry.workspaceId === workspaceId && entry.promptKey === promptKey
|
|
1507
|
+
) ?? null;
|
|
1508
|
+
}
|
|
1509
|
+
function hasSetupPromptSkip(workspaceId, promptKey, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1510
|
+
return getSetupPromptDecision(workspaceId, promptKey, statePath) !== null;
|
|
1511
|
+
}
|
|
1512
|
+
function recordSetupPromptSkip(entry, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1513
|
+
return updateWizardState((current) => {
|
|
1514
|
+
const existingEntries = current.setupPromptDecisions?.entries ?? [];
|
|
1515
|
+
const withoutExisting = existingEntries.filter(
|
|
1516
|
+
(existing) => !(existing.workspaceId === entry.workspaceId && existing.promptKey === entry.promptKey)
|
|
1517
|
+
);
|
|
1518
|
+
return {
|
|
1519
|
+
...current,
|
|
1520
|
+
setupPromptDecisions: {
|
|
1521
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1522
|
+
entries: [
|
|
1523
|
+
...withoutExisting,
|
|
1524
|
+
{
|
|
1525
|
+
promptKey: entry.promptKey,
|
|
1526
|
+
skippedAt: entry.skippedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
1527
|
+
status: "skipped",
|
|
1528
|
+
workspaceId: entry.workspaceId,
|
|
1529
|
+
...entry.workspaceName ? { workspaceName: entry.workspaceName } : {}
|
|
1530
|
+
}
|
|
1531
|
+
]
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
}, statePath);
|
|
1535
|
+
}
|
|
1461
1536
|
function writeWizardState(value, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1462
1537
|
const record = sanitizeWizardStateRecord(value);
|
|
1463
1538
|
writeJsonFile(statePath, record, { mode: 384 });
|
|
@@ -5912,7 +5987,7 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5912
5987
|
}
|
|
5913
5988
|
const { prompts } = options;
|
|
5914
5989
|
const setupChoice = await prompts.select({
|
|
5915
|
-
message: "Daily Brief
|
|
5990
|
+
message: "Set up Daily Brief now?",
|
|
5916
5991
|
initialValue: DAILY_BRIEF_SETUP_CHOICES.defaults,
|
|
5917
5992
|
options: [
|
|
5918
5993
|
{
|
|
@@ -5922,12 +5997,12 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5922
5997
|
},
|
|
5923
5998
|
{
|
|
5924
5999
|
value: DAILY_BRIEF_SETUP_CHOICES.customize,
|
|
5925
|
-
label: "Customize",
|
|
6000
|
+
label: "Customize baselines",
|
|
5926
6001
|
hint: "Answer baseline and delivery questions."
|
|
5927
6002
|
},
|
|
5928
6003
|
{
|
|
5929
6004
|
value: DAILY_BRIEF_SETUP_CHOICES.skip,
|
|
5930
|
-
label: "Skip",
|
|
6005
|
+
label: "Skip and remember",
|
|
5931
6006
|
hint: "Do not ask again unless you pass --daily-brief."
|
|
5932
6007
|
}
|
|
5933
6008
|
]
|
|
@@ -7391,6 +7466,9 @@ async function maybeCaptureSetupIntent(input) {
|
|
|
7391
7466
|
if (!input.interactive || !input.workspace) {
|
|
7392
7467
|
return "skipped";
|
|
7393
7468
|
}
|
|
7469
|
+
if (hasSetupPromptSkip(input.workspace.id, "setup_intent")) {
|
|
7470
|
+
return "skipped";
|
|
7471
|
+
}
|
|
7394
7472
|
const prompt = await textPrompt({
|
|
7395
7473
|
message: "In one line, what do you want OrgX to move first? (blank to skip \u2014 you can start from the dashboard)",
|
|
7396
7474
|
placeholder: "e.g. open a warm-intro loop to 50 design-led SaaS founders",
|
|
@@ -7406,6 +7484,11 @@ async function maybeCaptureSetupIntent(input) {
|
|
|
7406
7484
|
}
|
|
7407
7485
|
const intentText = typeof prompt === "string" ? prompt.trim() : "";
|
|
7408
7486
|
if (!intentText) {
|
|
7487
|
+
recordSetupPromptSkip({
|
|
7488
|
+
promptKey: "setup_intent",
|
|
7489
|
+
workspaceId: input.workspace.id,
|
|
7490
|
+
workspaceName: input.workspace.name
|
|
7491
|
+
});
|
|
7409
7492
|
return "skipped";
|
|
7410
7493
|
}
|
|
7411
7494
|
const spinner = createOrgxSpinner("Routing");
|
|
@@ -7640,7 +7723,11 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7640
7723
|
const storedFirstValueInitiative = existingState?.firstValueInitiative?.workspaceId === input.workspace.id ? existingState.firstValueInitiative : void 0;
|
|
7641
7724
|
let effectiveInitiativeId = providedInitiativeId || storedDemoInitiative?.id || storedFirstValueInitiative?.id;
|
|
7642
7725
|
let firstValueInitiative = providedInitiativeId || storedDemoInitiative ? null : firstValueRecordToResult(storedFirstValueInitiative);
|
|
7643
|
-
|
|
7726
|
+
const firstInitiativeSkipped = hasSetupPromptSkip(
|
|
7727
|
+
input.workspace.id,
|
|
7728
|
+
"first_initiative"
|
|
7729
|
+
);
|
|
7730
|
+
if (!effectiveInitiativeId && !firstInitiativeSkipped) {
|
|
7644
7731
|
const firstInitiativeChoice = await selectPrompt({
|
|
7645
7732
|
initialValue: "yes",
|
|
7646
7733
|
message: `Create your first OrgX initiative in ${input.workspace.name}?`,
|
|
@@ -7697,10 +7784,20 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7697
7784
|
const message = error instanceof Error ? error.message : String(error);
|
|
7698
7785
|
console.log(` ${ICON.warn} ${pc3.yellow("initiative")} ${pc3.dim(message)}`);
|
|
7699
7786
|
}
|
|
7787
|
+
} else if (firstInitiativeChoice === "no") {
|
|
7788
|
+
recordSetupPromptSkip({
|
|
7789
|
+
promptKey: "first_initiative",
|
|
7790
|
+
workspaceId: input.workspace.id,
|
|
7791
|
+
workspaceName: input.workspace.name
|
|
7792
|
+
});
|
|
7700
7793
|
}
|
|
7701
7794
|
}
|
|
7702
7795
|
const hasOnboardingTask = existingState?.onboardingTask?.workspaceId === input.workspace.id;
|
|
7703
|
-
|
|
7796
|
+
const onboardingTaskSkipped = hasSetupPromptSkip(
|
|
7797
|
+
input.workspace.id,
|
|
7798
|
+
"onboarding_task"
|
|
7799
|
+
);
|
|
7800
|
+
if (!hasOnboardingTask && effectiveInitiativeId && !onboardingTaskSkipped) {
|
|
7704
7801
|
let shouldCreateOnboardingTask = firstValueInitiative !== null;
|
|
7705
7802
|
if (!shouldCreateOnboardingTask) {
|
|
7706
7803
|
const onboardingChoice = await selectPrompt({
|
|
@@ -7716,6 +7813,13 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7716
7813
|
return "cancelled";
|
|
7717
7814
|
}
|
|
7718
7815
|
shouldCreateOnboardingTask = onboardingChoice === "yes";
|
|
7816
|
+
if (onboardingChoice === "no") {
|
|
7817
|
+
recordSetupPromptSkip({
|
|
7818
|
+
promptKey: "onboarding_task",
|
|
7819
|
+
workspaceId: input.workspace.id,
|
|
7820
|
+
workspaceName: input.workspace.name
|
|
7821
|
+
});
|
|
7822
|
+
}
|
|
7719
7823
|
}
|
|
7720
7824
|
if (shouldCreateOnboardingTask) {
|
|
7721
7825
|
const spinner = createOrgxSpinner("Creating onboarding workstream and starter task");
|
|
@@ -7755,7 +7859,8 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7755
7859
|
}
|
|
7756
7860
|
const refreshedState = readWizardState();
|
|
7757
7861
|
const hasAgentRoster = refreshedState?.agentRoster?.workspaceId === input.workspace.id;
|
|
7758
|
-
|
|
7862
|
+
const agentRosterSkipped = hasSetupPromptSkip(input.workspace.id, "agent_roster");
|
|
7863
|
+
if (!hasAgentRoster && !agentRosterSkipped) {
|
|
7759
7864
|
const rosterChoice = await selectPrompt({
|
|
7760
7865
|
initialValue: "default",
|
|
7761
7866
|
message: `Set up an OrgX agent roster for ${input.workspace.name}?`,
|
|
@@ -7791,6 +7896,11 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7791
7896
|
);
|
|
7792
7897
|
} else {
|
|
7793
7898
|
console.log(` ${ICON.skip} ${pc3.dim("agent roster skipped")} ${pc3.dim("(no agents selected)")}`);
|
|
7899
|
+
recordSetupPromptSkip({
|
|
7900
|
+
promptKey: "agent_roster",
|
|
7901
|
+
workspaceId: input.workspace.id,
|
|
7902
|
+
workspaceName: input.workspace.name
|
|
7903
|
+
});
|
|
7794
7904
|
}
|
|
7795
7905
|
} else if (rosterChoice === "default") {
|
|
7796
7906
|
const roster = ensureDefaultAgentRoster(input.workspace);
|
|
@@ -7808,6 +7918,12 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7808
7918
|
}
|
|
7809
7919
|
)
|
|
7810
7920
|
);
|
|
7921
|
+
} else if (rosterChoice === "no") {
|
|
7922
|
+
recordSetupPromptSkip({
|
|
7923
|
+
promptKey: "agent_roster",
|
|
7924
|
+
workspaceId: input.workspace.id,
|
|
7925
|
+
workspaceName: input.workspace.name
|
|
7926
|
+
});
|
|
7811
7927
|
}
|
|
7812
7928
|
}
|
|
7813
7929
|
return "configured";
|
|
@@ -7887,11 +8003,11 @@ async function maybeInstallOptionalCompanionPlugins(input) {
|
|
|
7887
8003
|
}
|
|
7888
8004
|
function printAuthStatus(status) {
|
|
7889
8005
|
if (!status.configured) {
|
|
7890
|
-
console.log(` ${ICON.warn} ${pc3.yellow("
|
|
8006
|
+
console.log(` ${ICON.warn} ${pc3.yellow("not paired")} run ${pc3.cyan(`${getCmd()} auth login`)} to pair this terminal`);
|
|
7891
8007
|
return;
|
|
7892
8008
|
}
|
|
7893
8009
|
const icon = status.ok ? ICON.ok : ICON.err;
|
|
7894
|
-
const state = status.ok ? pc3.green("
|
|
8010
|
+
const state = status.ok ? pc3.green("paired ") : status.skipped ? pc3.yellow("skipped ") : pc3.red("invalid ");
|
|
7895
8011
|
const via = pc3.dim(formatAuthSource(status.source));
|
|
7896
8012
|
console.log(` ${icon} ${state} ${pc3.bold(status.keyPrefix ?? "unknown")} ${via}`);
|
|
7897
8013
|
if (!status.ok && status.error) {
|
|
@@ -7963,7 +8079,7 @@ function printDoctorReport(report, assessment) {
|
|
|
7963
8079
|
async function main() {
|
|
7964
8080
|
const program = new Command();
|
|
7965
8081
|
program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
|
|
7966
|
-
const pkgVersion = true ? "0.1.
|
|
8082
|
+
const pkgVersion = true ? "0.1.25" : void 0;
|
|
7967
8083
|
program.version(pkgVersion ?? "unknown", "-V, --version");
|
|
7968
8084
|
program.hook("preAction", () => {
|
|
7969
8085
|
console.log(renderBanner(pkgVersion));
|
|
@@ -8091,9 +8207,9 @@ async function main() {
|
|
|
8091
8207
|
console.log("");
|
|
8092
8208
|
if (interactive) {
|
|
8093
8209
|
const choice = await selectPrompt({
|
|
8094
|
-
message: "
|
|
8210
|
+
message: "Pair this terminal with your OrgX account to finish setup",
|
|
8095
8211
|
options: [
|
|
8096
|
-
{ value: "login", label: "Open browser to
|
|
8212
|
+
{ value: "login", label: "Open browser to pair", hint: "recommended" },
|
|
8097
8213
|
{ value: "skip", label: "Skip for now", hint: `run \`${getCmd()} auth login\` later` }
|
|
8098
8214
|
]
|
|
8099
8215
|
});
|
|
@@ -8105,19 +8221,19 @@ async function main() {
|
|
|
8105
8221
|
const loginOk = await runBrowserLogin({ telemetrySource: "browser_pairing" });
|
|
8106
8222
|
if (!loginOk) {
|
|
8107
8223
|
console.log(`
|
|
8108
|
-
${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login`)} ${pc3.dim("to
|
|
8224
|
+
${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login`)} ${pc3.dim("to start a fresh browser pairing")}`);
|
|
8109
8225
|
console.log(` ${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login --api-key`)} ${pc3.dim("to paste a key directly")}`);
|
|
8110
8226
|
return;
|
|
8111
8227
|
}
|
|
8112
8228
|
resolvedAuth = await resolveOrgxAuth();
|
|
8113
8229
|
} else {
|
|
8114
8230
|
console.log(`
|
|
8115
|
-
${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login`)} ${pc3.dim("to
|
|
8231
|
+
${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login`)} ${pc3.dim("to pair when ready")}`);
|
|
8116
8232
|
return;
|
|
8117
8233
|
}
|
|
8118
8234
|
} else {
|
|
8119
8235
|
console.log(
|
|
8120
|
-
` ${ICON.warn} ${pc3.yellow("
|
|
8236
|
+
` ${ICON.warn} ${pc3.yellow("Terminal not paired.")} Run ${pc3.cyan(`${getCmd()} auth login`)} to pair it.`
|
|
8121
8237
|
);
|
|
8122
8238
|
return;
|
|
8123
8239
|
}
|
|
@@ -8297,9 +8413,9 @@ async function main() {
|
|
|
8297
8413
|
has_base_url: false
|
|
8298
8414
|
});
|
|
8299
8415
|
const openclawResults = detectSurface("openclaw").detected ? await addSurface("openclaw") : [];
|
|
8300
|
-
spinner.succeed("OrgX account
|
|
8416
|
+
spinner.succeed("OrgX account paired");
|
|
8301
8417
|
await syncContinuityAfterAuth();
|
|
8302
|
-
console.log(` ${ICON.ok} ${pc3.green("
|
|
8418
|
+
console.log(` ${ICON.ok} ${pc3.green("paired ")} ${pc3.bold(stored.keyPrefix)} ${pc3.dim("browser sign-in")}`);
|
|
8303
8419
|
if (openclawResults.length > 0) {
|
|
8304
8420
|
console.log("");
|
|
8305
8421
|
printMutationResults(openclawResults);
|
|
@@ -8312,22 +8428,36 @@ async function main() {
|
|
|
8312
8428
|
return false;
|
|
8313
8429
|
}
|
|
8314
8430
|
}
|
|
8431
|
+
function shortPairingId(pairingId) {
|
|
8432
|
+
return pairingId.length > 13 ? `${pairingId.slice(0, 8)}...${pairingId.slice(-4)}` : pairingId;
|
|
8433
|
+
}
|
|
8434
|
+
function formatPairingExpiry(expiresAt) {
|
|
8435
|
+
const remainingMs = Date.parse(expiresAt) - Date.now();
|
|
8436
|
+
if (!Number.isFinite(remainingMs) || remainingMs <= 0) return "expired";
|
|
8437
|
+
const minutes = Math.ceil(remainingMs / 6e4);
|
|
8438
|
+
return minutes <= 1 ? "<1m" : `${minutes}m`;
|
|
8439
|
+
}
|
|
8315
8440
|
async function runBrowserLogin(opts = {}) {
|
|
8316
8441
|
const installationId = getOrCreateWizardInstallationId();
|
|
8442
|
+
const deviceName = opts.deviceName ?? hostname();
|
|
8317
8443
|
const spinner = createOrgxSpinner("Starting OrgX browser pairing");
|
|
8318
8444
|
spinner.start();
|
|
8319
8445
|
try {
|
|
8320
8446
|
const pairing = await startBrowserPairing({
|
|
8321
8447
|
installationId,
|
|
8322
8448
|
baseUrl: opts.baseUrl,
|
|
8323
|
-
deviceName
|
|
8449
|
+
deviceName,
|
|
8324
8450
|
platform: process.platform
|
|
8325
8451
|
});
|
|
8326
|
-
spinner.succeed("Browser pairing
|
|
8452
|
+
spinner.succeed("Browser pairing ready");
|
|
8327
8453
|
console.log(`
|
|
8328
|
-
${pc3.dim("Open this URL to
|
|
8454
|
+
${pc3.dim("Open this URL to approve terminal pairing:")}`);
|
|
8329
8455
|
console.log(` ${pc3.cyan(pairing.connectUrl)}
|
|
8330
8456
|
`);
|
|
8457
|
+
console.log(
|
|
8458
|
+
` ${pc3.dim("session ")} ${pc3.bold(shortPairingId(pairing.pairingId))} ${pc3.dim("device")} ${pc3.bold(deviceName)} ${pc3.dim("expires")} ${pc3.bold(formatPairingExpiry(pairing.expiresAt))}
|
|
8459
|
+
`
|
|
8460
|
+
);
|
|
8331
8461
|
if (opts.open !== false) {
|
|
8332
8462
|
const openResult = openBrowser(pairing.connectUrl);
|
|
8333
8463
|
if (!openResult.ok && openResult.error) {
|
|
@@ -8343,33 +8473,38 @@ async function main() {
|
|
|
8343
8473
|
pollToken: pairing.pollToken,
|
|
8344
8474
|
timeoutMs: (opts.timeout ?? 600) * 1e3
|
|
8345
8475
|
});
|
|
8346
|
-
spinner.text = "Verifying
|
|
8476
|
+
spinner.text = "Verifying paired account...";
|
|
8347
8477
|
const result = await verifyAndPersistAuth(ready.key, {
|
|
8348
8478
|
...opts.baseUrl !== void 0 ? { baseUrl: opts.baseUrl } : {},
|
|
8349
8479
|
...opts.telemetrySource ? { telemetrySource: opts.telemetrySource } : {}
|
|
8350
8480
|
});
|
|
8351
8481
|
if (!("stored" in result)) {
|
|
8352
|
-
spinner.fail("Pairing completed but
|
|
8482
|
+
spinner.fail("Pairing completed but OrgX rejected the key");
|
|
8353
8483
|
console.log(` ${pc3.red(result.verification.error ?? `HTTP ${result.verification.status ?? "error"}`)}`);
|
|
8354
8484
|
console.log(` ${pc3.dim("The browser flow finished, but OrgX rejected the key. Try again or check your account at useorgx.com.")}`);
|
|
8355
8485
|
return false;
|
|
8356
8486
|
}
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8487
|
+
let ackConfirmed = false;
|
|
8488
|
+
try {
|
|
8489
|
+
await acknowledgeBrowserPairing({
|
|
8490
|
+
baseUrl: opts.baseUrl,
|
|
8491
|
+
pairingId: pairing.pairingId,
|
|
8492
|
+
pollToken: pairing.pollToken
|
|
8493
|
+
});
|
|
8494
|
+
ackConfirmed = true;
|
|
8495
|
+
} catch (error) {
|
|
8362
8496
|
console.log(pc3.dim(`Pairing ack failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
8363
|
-
}
|
|
8364
|
-
spinner.succeed("OrgX account
|
|
8497
|
+
}
|
|
8498
|
+
spinner.succeed("OrgX account paired");
|
|
8365
8499
|
await syncContinuityAfterAuth({
|
|
8366
8500
|
executionMode: ready.executionMode,
|
|
8367
8501
|
workspaceName: ready.workspaceName
|
|
8368
8502
|
});
|
|
8369
|
-
console.log(` ${ICON.ok} ${pc3.green("
|
|
8503
|
+
console.log(` ${ICON.ok} ${pc3.green("paired ")} ${pc3.bold(result.stored.keyPrefix ?? result.verification.keyPrefix ?? "unknown")} ${pc3.dim("wizard auth store")}`);
|
|
8370
8504
|
if (ready.workspaceName) {
|
|
8371
8505
|
console.log(` ${ICON.ok} ${pc3.green("workspace ")} ${pc3.bold(ready.workspaceName)}`);
|
|
8372
8506
|
}
|
|
8507
|
+
console.log(` ${ackConfirmed ? ICON.ok : ICON.warn} ${ackConfirmed ? pc3.green("ack ") : pc3.yellow("ack ")} ${pc3.bold(ackConfirmed ? "terminal confirmed" : "browser delivery pending")} ${pc3.dim(shortPairingId(pairing.pairingId))}`);
|
|
8373
8508
|
if (result.openclawResults.length > 0) {
|
|
8374
8509
|
console.log("");
|
|
8375
8510
|
printMutationResults(result.openclawResults);
|
|
@@ -8382,8 +8517,8 @@ async function main() {
|
|
|
8382
8517
|
return false;
|
|
8383
8518
|
}
|
|
8384
8519
|
}
|
|
8385
|
-
const auth = program.command("auth").description("
|
|
8386
|
-
auth.command("status").description("Show
|
|
8520
|
+
const auth = program.command("auth").description("Pair this terminal with an OrgX account.");
|
|
8521
|
+
auth.command("status").description("Show which OrgX account this terminal is paired with.").action(async () => {
|
|
8387
8522
|
const spinner = createOrgxSpinner("Checking OrgX auth");
|
|
8388
8523
|
spinner.start();
|
|
8389
8524
|
const status = await checkOrgxAuth();
|
|
@@ -8391,7 +8526,7 @@ async function main() {
|
|
|
8391
8526
|
console.log(pc3.dim(" account"));
|
|
8392
8527
|
printAuthStatus(status);
|
|
8393
8528
|
});
|
|
8394
|
-
auth.command("login").description("
|
|
8529
|
+
auth.command("login").description("Open the browser pairing flow and store a scoped OrgX key for this terminal.").option("--api-key <key>", "Bypass browser auth and verify this OrgX API key directly.").option("--base-url <url>", "OrgX base URL (for OpenClaw pairing fallback).").option("--device-name <name>", "Device name shown during OpenClaw pairing.").option("--no-open", "Do not automatically open the browser auth URL.").option("--pairing", "Force the terminal pairing fallback instead of browser sign-in.").option("--timeout <seconds>", "How long to wait for browser auth before giving up.", parseTimeoutSeconds, 600).action(async (options) => {
|
|
8395
8530
|
if (options.apiKey) {
|
|
8396
8531
|
const spinner = createOrgxSpinner("Verifying OrgX API key");
|
|
8397
8532
|
spinner.start();
|
|
@@ -8404,9 +8539,9 @@ async function main() {
|
|
|
8404
8539
|
printAuthStatus(result.verification);
|
|
8405
8540
|
return;
|
|
8406
8541
|
}
|
|
8407
|
-
spinner.succeed("OrgX account
|
|
8542
|
+
spinner.succeed("OrgX account paired");
|
|
8408
8543
|
await syncContinuityAfterAuth();
|
|
8409
|
-
console.log(` ${ICON.ok} ${pc3.green("
|
|
8544
|
+
console.log(` ${ICON.ok} ${pc3.green("paired ")} ${pc3.bold(result.stored.keyPrefix ?? result.verification.keyPrefix ?? "unknown")} ${pc3.dim("wizard auth store")}`);
|
|
8410
8545
|
if (result.openclawResults.length > 0) {
|
|
8411
8546
|
console.log("");
|
|
8412
8547
|
printMutationResults(result.openclawResults);
|
|
@@ -8429,7 +8564,7 @@ async function main() {
|
|
|
8429
8564
|
timeout: options.timeout
|
|
8430
8565
|
});
|
|
8431
8566
|
if (!pkceOk) {
|
|
8432
|
-
console.log(pc3.dim("\n
|
|
8567
|
+
console.log(pc3.dim("\n Browser sign-in did not finish. Opening the terminal pairing fallback..."));
|
|
8433
8568
|
await runBrowserLogin({
|
|
8434
8569
|
...options.baseUrl !== void 0 ? { baseUrl: options.baseUrl } : {},
|
|
8435
8570
|
...options.deviceName !== void 0 ? { deviceName: options.deviceName } : {},
|
|
@@ -8451,9 +8586,9 @@ async function main() {
|
|
|
8451
8586
|
printAuthStatus(result.verification);
|
|
8452
8587
|
return;
|
|
8453
8588
|
}
|
|
8454
|
-
spinner.succeed("OrgX account
|
|
8589
|
+
spinner.succeed("OrgX account paired");
|
|
8455
8590
|
await syncContinuityAfterAuth();
|
|
8456
|
-
console.log(` ${ICON.ok} ${pc3.green("
|
|
8591
|
+
console.log(` ${ICON.ok} ${pc3.green("paired ")} ${pc3.bold(result.stored.keyPrefix ?? result.verification.keyPrefix ?? "unknown")} ${pc3.dim("wizard auth store")}`);
|
|
8457
8592
|
if (result.openclawResults.length > 0) {
|
|
8458
8593
|
console.log("");
|
|
8459
8594
|
printMutationResults(result.openclawResults);
|