@useorgx/wizard 0.1.23 → 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 +421 -111
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1337,6 +1337,80 @@ function parsePeopleFirstCapture(value) {
|
|
|
1337
1337
|
entries
|
|
1338
1338
|
};
|
|
1339
1339
|
}
|
|
1340
|
+
function parseDailyBriefOnboardingEntry(value) {
|
|
1341
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1342
|
+
return void 0;
|
|
1343
|
+
}
|
|
1344
|
+
const record = value;
|
|
1345
|
+
const status = record.status;
|
|
1346
|
+
if (!isNonEmptyString2(record.workspaceId) || status !== "completed" && status !== "skipped") {
|
|
1347
|
+
return void 0;
|
|
1348
|
+
}
|
|
1349
|
+
const completedAt = isNonEmptyString2(record.completedAt) ? record.completedAt.trim() : void 0;
|
|
1350
|
+
const skippedAt = isNonEmptyString2(record.skippedAt) ? record.skippedAt.trim() : void 0;
|
|
1351
|
+
if (status === "completed" && !completedAt) return void 0;
|
|
1352
|
+
if (status === "skipped" && !skippedAt) return void 0;
|
|
1353
|
+
return {
|
|
1354
|
+
workspaceId: record.workspaceId.trim(),
|
|
1355
|
+
status,
|
|
1356
|
+
...completedAt ? { completedAt } : {},
|
|
1357
|
+
...skippedAt ? { skippedAt } : {},
|
|
1358
|
+
...isNonEmptyString2(record.workspaceName) ? { workspaceName: record.workspaceName.trim() } : {}
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
function parseDailyBriefOnboarding(value) {
|
|
1362
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1363
|
+
return void 0;
|
|
1364
|
+
}
|
|
1365
|
+
const record = value;
|
|
1366
|
+
if (!isNonEmptyString2(record.updatedAt) || !Array.isArray(record.entries)) {
|
|
1367
|
+
return void 0;
|
|
1368
|
+
}
|
|
1369
|
+
const entries = record.entries.map((entry) => parseDailyBriefOnboardingEntry(entry)).filter(
|
|
1370
|
+
(entry) => Boolean(entry)
|
|
1371
|
+
);
|
|
1372
|
+
if (entries.length === 0) return void 0;
|
|
1373
|
+
return {
|
|
1374
|
+
updatedAt: record.updatedAt.trim(),
|
|
1375
|
+
entries
|
|
1376
|
+
};
|
|
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
|
+
}
|
|
1340
1414
|
function createWizardState(now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
1341
1415
|
return {
|
|
1342
1416
|
installationId: `wizard-${randomUUID()}`,
|
|
@@ -1352,6 +1426,8 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1352
1426
|
const onboardingTask = parseOnboardingTask(record.onboardingTask);
|
|
1353
1427
|
const skillFiles = parseSkillFiles(record.skillFiles);
|
|
1354
1428
|
const peopleFirstCapture = parsePeopleFirstCapture(record.peopleFirstCapture);
|
|
1429
|
+
const dailyBriefOnboarding = parseDailyBriefOnboarding(record.dailyBriefOnboarding);
|
|
1430
|
+
const setupPromptDecisions = parseSetupPromptDecisions(record.setupPromptDecisions);
|
|
1355
1431
|
return {
|
|
1356
1432
|
installationId: record.installationId.trim(),
|
|
1357
1433
|
createdAt: record.createdAt.trim(),
|
|
@@ -1362,7 +1438,9 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1362
1438
|
...firstValueInitiative ? { firstValueInitiative } : {},
|
|
1363
1439
|
...onboardingTask ? { onboardingTask } : {},
|
|
1364
1440
|
...skillFiles ? { skillFiles } : {},
|
|
1365
|
-
...peopleFirstCapture ? { peopleFirstCapture } : {}
|
|
1441
|
+
...peopleFirstCapture ? { peopleFirstCapture } : {},
|
|
1442
|
+
...dailyBriefOnboarding ? { dailyBriefOnboarding } : {},
|
|
1443
|
+
...setupPromptDecisions ? { setupPromptDecisions } : {}
|
|
1366
1444
|
};
|
|
1367
1445
|
}
|
|
1368
1446
|
function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
@@ -1391,8 +1469,70 @@ function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
|
1391
1469
|
if (skillFiles !== void 0) state.skillFiles = skillFiles;
|
|
1392
1470
|
const peopleFirstCapture = parsePeopleFirstCapture(parsed.peopleFirstCapture);
|
|
1393
1471
|
if (peopleFirstCapture !== void 0) state.peopleFirstCapture = peopleFirstCapture;
|
|
1472
|
+
const dailyBriefOnboarding = parseDailyBriefOnboarding(parsed.dailyBriefOnboarding);
|
|
1473
|
+
if (dailyBriefOnboarding !== void 0) {
|
|
1474
|
+
state.dailyBriefOnboarding = dailyBriefOnboarding;
|
|
1475
|
+
}
|
|
1476
|
+
const setupPromptDecisions = parseSetupPromptDecisions(parsed.setupPromptDecisions);
|
|
1477
|
+
if (setupPromptDecisions !== void 0) {
|
|
1478
|
+
state.setupPromptDecisions = setupPromptDecisions;
|
|
1479
|
+
}
|
|
1394
1480
|
return state;
|
|
1395
1481
|
}
|
|
1482
|
+
function getDailyBriefOnboardingDecision(workspaceId, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1483
|
+
const state = readWizardState(statePath);
|
|
1484
|
+
return state?.dailyBriefOnboarding?.entries.find(
|
|
1485
|
+
(entry) => entry.workspaceId === workspaceId
|
|
1486
|
+
) ?? null;
|
|
1487
|
+
}
|
|
1488
|
+
function recordDailyBriefOnboardingDecision(entry, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1489
|
+
return updateWizardState((current) => {
|
|
1490
|
+
const existingEntries = current.dailyBriefOnboarding?.entries ?? [];
|
|
1491
|
+
const withoutExisting = existingEntries.filter(
|
|
1492
|
+
(e) => e.workspaceId !== entry.workspaceId
|
|
1493
|
+
);
|
|
1494
|
+
return {
|
|
1495
|
+
...current,
|
|
1496
|
+
dailyBriefOnboarding: {
|
|
1497
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1498
|
+
entries: [...withoutExisting, entry]
|
|
1499
|
+
}
|
|
1500
|
+
};
|
|
1501
|
+
}, statePath);
|
|
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
|
+
}
|
|
1396
1536
|
function writeWizardState(value, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1397
1537
|
const record = sanitizeWizardStateRecord(value);
|
|
1398
1538
|
writeJsonFile(statePath, record, { mode: 384 });
|
|
@@ -5104,6 +5244,14 @@ async function runWorkspaceSetup(client, prompts, options) {
|
|
|
5104
5244
|
}
|
|
5105
5245
|
return createAndSelectWorkspace(client, prompts);
|
|
5106
5246
|
}
|
|
5247
|
+
if (options.skipIfConfigured && currentWorkspace) {
|
|
5248
|
+
return {
|
|
5249
|
+
defaultChanged: false,
|
|
5250
|
+
message: `Using "${currentWorkspace.name}" as the default OrgX workspace.`,
|
|
5251
|
+
status: "unchanged",
|
|
5252
|
+
workspace: currentWorkspace
|
|
5253
|
+
};
|
|
5254
|
+
}
|
|
5107
5255
|
const initialWorkspaceId = currentWorkspace?.id ?? workspaces.find((workspace) => workspace.isDefault)?.id ?? workspaces[0]?.id;
|
|
5108
5256
|
const selected = await prompts.select({
|
|
5109
5257
|
message: "Choose the OrgX workspace this machine should use by default.",
|
|
@@ -5744,20 +5892,73 @@ var BASELINE_PROMPTS = [
|
|
|
5744
5892
|
{ task_type: "launch_post", label: "Launch post", placeholder: "60" },
|
|
5745
5893
|
{ task_type: "architecture_doc", label: "Architecture doc", placeholder: "90" }
|
|
5746
5894
|
];
|
|
5895
|
+
var DAILY_BRIEF_SETUP_CHOICES = {
|
|
5896
|
+
defaults: "defaults",
|
|
5897
|
+
customize: "customize",
|
|
5898
|
+
skip: "skip"
|
|
5899
|
+
};
|
|
5900
|
+
function buildDefaultBaselines() {
|
|
5901
|
+
return BASELINE_PROMPTS.map((bp) => ({
|
|
5902
|
+
task_type: bp.task_type,
|
|
5903
|
+
minutes: Number.parseInt(bp.placeholder, 10),
|
|
5904
|
+
confidence: 0.4
|
|
5905
|
+
}));
|
|
5906
|
+
}
|
|
5907
|
+
function buildDefaultGoals() {
|
|
5908
|
+
return [
|
|
5909
|
+
{
|
|
5910
|
+
goal_type: "time_saved_weekly",
|
|
5911
|
+
target_value: 180,
|
|
5912
|
+
unit: "minutes",
|
|
5913
|
+
period: "weekly"
|
|
5914
|
+
}
|
|
5915
|
+
];
|
|
5916
|
+
}
|
|
5917
|
+
function normalizeSendTime(value) {
|
|
5918
|
+
return value.trim().length === 4 ? `0${value.trim()}` : value.trim();
|
|
5919
|
+
}
|
|
5920
|
+
function recordSkipped(workspace, statePath) {
|
|
5921
|
+
recordDailyBriefOnboardingDecision(
|
|
5922
|
+
{
|
|
5923
|
+
workspaceId: workspace.id,
|
|
5924
|
+
workspaceName: workspace.name,
|
|
5925
|
+
status: "skipped",
|
|
5926
|
+
skippedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5927
|
+
},
|
|
5928
|
+
statePath
|
|
5929
|
+
);
|
|
5930
|
+
return {
|
|
5931
|
+
status: "skipped_user",
|
|
5932
|
+
message: "Daily Brief setup skipped. Run `wizard setup --daily-brief` when ready."
|
|
5933
|
+
};
|
|
5934
|
+
}
|
|
5747
5935
|
async function runDailyBriefOnboarding(options) {
|
|
5748
|
-
if (!options.interactive) {
|
|
5749
|
-
return {
|
|
5750
|
-
status: "skipped_non_interactive",
|
|
5751
|
-
message: "Daily Brief onboarding skipped \u2014 not attached to a TTY."
|
|
5752
|
-
};
|
|
5753
|
-
}
|
|
5754
5936
|
if (!options.workspace) {
|
|
5755
5937
|
return {
|
|
5756
5938
|
status: "skipped_no_workspace",
|
|
5757
5939
|
message: "Daily Brief onboarding skipped \u2014 no workspace resolved."
|
|
5758
5940
|
};
|
|
5759
5941
|
}
|
|
5760
|
-
|
|
5942
|
+
if (options.skip) {
|
|
5943
|
+
return recordSkipped(options.workspace, options.statePath);
|
|
5944
|
+
}
|
|
5945
|
+
const localDecision = getDailyBriefOnboardingDecision(
|
|
5946
|
+
options.workspace.id,
|
|
5947
|
+
options.statePath
|
|
5948
|
+
);
|
|
5949
|
+
if (!options.force && localDecision) {
|
|
5950
|
+
return {
|
|
5951
|
+
status: "skipped_already_completed",
|
|
5952
|
+
message: localDecision.status === "completed" ? "Daily Brief onboarding already completed for this workspace." : "Daily Brief setup was skipped for this workspace. Run `wizard setup --daily-brief` to configure."
|
|
5953
|
+
};
|
|
5954
|
+
}
|
|
5955
|
+
if (!options.interactive) {
|
|
5956
|
+
return {
|
|
5957
|
+
status: "skipped_non_interactive",
|
|
5958
|
+
message: "Daily Brief onboarding skipped \u2014 not attached to a TTY."
|
|
5959
|
+
};
|
|
5960
|
+
}
|
|
5961
|
+
const auth = await resolveOrgxAuth(options.authOptions);
|
|
5761
5962
|
if (!auth) {
|
|
5762
5963
|
return {
|
|
5763
5964
|
status: "failed",
|
|
@@ -5769,6 +5970,15 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5769
5970
|
if (state) {
|
|
5770
5971
|
const row = state.workspaces.find((w) => w.id === options.workspace.id);
|
|
5771
5972
|
if (row?.onboardingCompletedAt) {
|
|
5973
|
+
recordDailyBriefOnboardingDecision(
|
|
5974
|
+
{
|
|
5975
|
+
workspaceId: options.workspace.id,
|
|
5976
|
+
workspaceName: options.workspace.name,
|
|
5977
|
+
status: "completed",
|
|
5978
|
+
completedAt: row.onboardingCompletedAt
|
|
5979
|
+
},
|
|
5980
|
+
options.statePath
|
|
5981
|
+
);
|
|
5772
5982
|
return {
|
|
5773
5983
|
status: "skipped_already_completed",
|
|
5774
5984
|
message: "Daily Brief onboarding already completed for this workspace."
|
|
@@ -5776,93 +5986,116 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5776
5986
|
}
|
|
5777
5987
|
}
|
|
5778
5988
|
const { prompts } = options;
|
|
5779
|
-
const
|
|
5780
|
-
message: "Set up
|
|
5781
|
-
initialValue:
|
|
5989
|
+
const setupChoice = await prompts.select({
|
|
5990
|
+
message: "Set up Daily Brief now?",
|
|
5991
|
+
initialValue: DAILY_BRIEF_SETUP_CHOICES.defaults,
|
|
5992
|
+
options: [
|
|
5993
|
+
{
|
|
5994
|
+
value: DAILY_BRIEF_SETUP_CHOICES.defaults,
|
|
5995
|
+
label: "Use defaults",
|
|
5996
|
+
hint: "20m code review, 45m PRD, 07:00 daily."
|
|
5997
|
+
},
|
|
5998
|
+
{
|
|
5999
|
+
value: DAILY_BRIEF_SETUP_CHOICES.customize,
|
|
6000
|
+
label: "Customize baselines",
|
|
6001
|
+
hint: "Answer baseline and delivery questions."
|
|
6002
|
+
},
|
|
6003
|
+
{
|
|
6004
|
+
value: DAILY_BRIEF_SETUP_CHOICES.skip,
|
|
6005
|
+
label: "Skip and remember",
|
|
6006
|
+
hint: "Do not ask again unless you pass --daily-brief."
|
|
6007
|
+
}
|
|
6008
|
+
]
|
|
5782
6009
|
});
|
|
5783
|
-
if (prompts.isCancel(
|
|
6010
|
+
if (prompts.isCancel(setupChoice)) {
|
|
5784
6011
|
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5785
6012
|
}
|
|
5786
|
-
if (
|
|
5787
|
-
return
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
6013
|
+
if (setupChoice === DAILY_BRIEF_SETUP_CHOICES.skip) {
|
|
6014
|
+
return recordSkipped(options.workspace, options.statePath);
|
|
6015
|
+
}
|
|
6016
|
+
const shouldCustomize = setupChoice === DAILY_BRIEF_SETUP_CHOICES.customize;
|
|
6017
|
+
const baselines = shouldCustomize ? [] : buildDefaultBaselines();
|
|
6018
|
+
if (shouldCustomize) {
|
|
6019
|
+
for (const bp of BASELINE_PROMPTS) {
|
|
6020
|
+
const answer = await prompts.text({
|
|
6021
|
+
message: `${bp.label} minutes`,
|
|
6022
|
+
placeholder: bp.placeholder,
|
|
6023
|
+
validate(value) {
|
|
6024
|
+
if (!value || value.trim() === "") return void 0;
|
|
6025
|
+
const n = Number.parseInt(value, 10);
|
|
6026
|
+
if (!Number.isFinite(n) || n <= 0 || n > 24 * 60) {
|
|
6027
|
+
return "Enter 1-1440 or leave blank.";
|
|
6028
|
+
}
|
|
6029
|
+
return void 0;
|
|
6030
|
+
}
|
|
6031
|
+
});
|
|
6032
|
+
if (prompts.isCancel(answer)) {
|
|
6033
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
6034
|
+
}
|
|
6035
|
+
if (typeof answer === "string" && answer.trim() !== "") {
|
|
6036
|
+
const minutes = Number.parseInt(answer, 10);
|
|
6037
|
+
if (Number.isFinite(minutes) && minutes > 0) {
|
|
6038
|
+
baselines.push({ task_type: bp.task_type, minutes, confidence: 0.5 });
|
|
6039
|
+
}
|
|
6040
|
+
}
|
|
6041
|
+
}
|
|
5791
6042
|
}
|
|
5792
|
-
const
|
|
5793
|
-
|
|
5794
|
-
const
|
|
5795
|
-
message:
|
|
5796
|
-
placeholder:
|
|
6043
|
+
const goals = shouldCustomize ? [] : buildDefaultGoals();
|
|
6044
|
+
if (shouldCustomize) {
|
|
6045
|
+
const goalAnswer = await prompts.text({
|
|
6046
|
+
message: "Weekly time-saved target minutes",
|
|
6047
|
+
placeholder: "180",
|
|
5797
6048
|
validate(value) {
|
|
5798
6049
|
if (!value || value.trim() === "") return void 0;
|
|
5799
6050
|
const n = Number.parseInt(value, 10);
|
|
5800
|
-
if (!Number.isFinite(n) || n <= 0
|
|
5801
|
-
return "Enter
|
|
6051
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
6052
|
+
return "Enter a positive number or leave blank.";
|
|
5802
6053
|
}
|
|
5803
6054
|
return void 0;
|
|
5804
6055
|
}
|
|
5805
6056
|
});
|
|
5806
|
-
if (prompts.isCancel(
|
|
6057
|
+
if (prompts.isCancel(goalAnswer)) {
|
|
5807
6058
|
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5808
6059
|
}
|
|
5809
|
-
if (typeof
|
|
5810
|
-
const
|
|
5811
|
-
if (Number.isFinite(
|
|
5812
|
-
|
|
6060
|
+
if (typeof goalAnswer === "string" && goalAnswer.trim() !== "") {
|
|
6061
|
+
const target = Number.parseInt(goalAnswer, 10);
|
|
6062
|
+
if (Number.isFinite(target) && target > 0) {
|
|
6063
|
+
goals.push({
|
|
6064
|
+
goal_type: "time_saved_weekly",
|
|
6065
|
+
target_value: target,
|
|
6066
|
+
unit: "minutes",
|
|
6067
|
+
period: "weekly"
|
|
6068
|
+
});
|
|
5813
6069
|
}
|
|
5814
6070
|
}
|
|
5815
6071
|
}
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
6072
|
+
let sendTimeLocal = "07:00";
|
|
6073
|
+
let onlyOnAttention = false;
|
|
6074
|
+
if (shouldCustomize) {
|
|
6075
|
+
const sendTimeAnswer = await prompts.text({
|
|
6076
|
+
message: "Daily brief time (HH:MM)",
|
|
6077
|
+
placeholder: "07:00",
|
|
6078
|
+
validate(value) {
|
|
6079
|
+
if (!value || value.trim() === "") return void 0;
|
|
6080
|
+
if (!/^\d{1,2}:\d{2}$/.test(value.trim())) {
|
|
6081
|
+
return "Use HH:MM (24h).";
|
|
6082
|
+
}
|
|
6083
|
+
return void 0;
|
|
5825
6084
|
}
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
if (prompts.isCancel(goalAnswer)) {
|
|
5830
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5831
|
-
}
|
|
5832
|
-
if (typeof goalAnswer === "string" && goalAnswer.trim() !== "") {
|
|
5833
|
-
const target = Number.parseInt(goalAnswer, 10);
|
|
5834
|
-
if (Number.isFinite(target) && target > 0) {
|
|
5835
|
-
goals.push({
|
|
5836
|
-
goal_type: "time_saved_weekly",
|
|
5837
|
-
target_value: target,
|
|
5838
|
-
unit: "minutes",
|
|
5839
|
-
period: "weekly"
|
|
5840
|
-
});
|
|
6085
|
+
});
|
|
6086
|
+
if (prompts.isCancel(sendTimeAnswer)) {
|
|
6087
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5841
6088
|
}
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
return "Use HH:MM (24h).";
|
|
5850
|
-
}
|
|
5851
|
-
return void 0;
|
|
6089
|
+
sendTimeLocal = typeof sendTimeAnswer === "string" && sendTimeAnswer.trim() ? normalizeSendTime(sendTimeAnswer) : "07:00";
|
|
6090
|
+
const onlyOnAttentionAnswer = await prompts.confirm({
|
|
6091
|
+
message: "Email only when attention is needed?",
|
|
6092
|
+
initialValue: false
|
|
6093
|
+
});
|
|
6094
|
+
if (prompts.isCancel(onlyOnAttentionAnswer)) {
|
|
6095
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5852
6096
|
}
|
|
5853
|
-
|
|
5854
|
-
if (prompts.isCancel(sendTimeAnswer)) {
|
|
5855
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5856
|
-
}
|
|
5857
|
-
const sendTimeLocal = typeof sendTimeAnswer === "string" && sendTimeAnswer.trim() ? sendTimeAnswer.trim().length === 4 ? `0${sendTimeAnswer.trim()}` : sendTimeAnswer.trim() : "07:00";
|
|
5858
|
-
const onlyOnAttentionAnswer = await prompts.confirm({
|
|
5859
|
-
message: "Only email when something needs your attention?",
|
|
5860
|
-
initialValue: false
|
|
5861
|
-
});
|
|
5862
|
-
if (prompts.isCancel(onlyOnAttentionAnswer)) {
|
|
5863
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
6097
|
+
onlyOnAttention = Boolean(onlyOnAttentionAnswer);
|
|
5864
6098
|
}
|
|
5865
|
-
const onlyOnAttention = Boolean(onlyOnAttentionAnswer);
|
|
5866
6099
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
5867
6100
|
const commitPayload = {
|
|
5868
6101
|
workspace_id: options.workspace.id,
|
|
@@ -5904,6 +6137,15 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5904
6137
|
}
|
|
5905
6138
|
const commitBody = await commitResponse.json().catch(() => ({}));
|
|
5906
6139
|
const previewUrl = typeof commitBody.daily_brief_preview_url === "string" ? commitBody.daily_brief_preview_url : "/today?mode=preview";
|
|
6140
|
+
recordDailyBriefOnboardingDecision(
|
|
6141
|
+
{
|
|
6142
|
+
workspaceId: options.workspace.id,
|
|
6143
|
+
workspaceName: options.workspace.name,
|
|
6144
|
+
status: "completed",
|
|
6145
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6146
|
+
},
|
|
6147
|
+
options.statePath
|
|
6148
|
+
);
|
|
5907
6149
|
return {
|
|
5908
6150
|
status: "completed",
|
|
5909
6151
|
message: "Your Daily Brief is configured. First brief lands tomorrow.",
|
|
@@ -7224,6 +7466,9 @@ async function maybeCaptureSetupIntent(input) {
|
|
|
7224
7466
|
if (!input.interactive || !input.workspace) {
|
|
7225
7467
|
return "skipped";
|
|
7226
7468
|
}
|
|
7469
|
+
if (hasSetupPromptSkip(input.workspace.id, "setup_intent")) {
|
|
7470
|
+
return "skipped";
|
|
7471
|
+
}
|
|
7227
7472
|
const prompt = await textPrompt({
|
|
7228
7473
|
message: "In one line, what do you want OrgX to move first? (blank to skip \u2014 you can start from the dashboard)",
|
|
7229
7474
|
placeholder: "e.g. open a warm-intro loop to 50 design-led SaaS founders",
|
|
@@ -7239,6 +7484,11 @@ async function maybeCaptureSetupIntent(input) {
|
|
|
7239
7484
|
}
|
|
7240
7485
|
const intentText = typeof prompt === "string" ? prompt.trim() : "";
|
|
7241
7486
|
if (!intentText) {
|
|
7487
|
+
recordSetupPromptSkip({
|
|
7488
|
+
promptKey: "setup_intent",
|
|
7489
|
+
workspaceId: input.workspace.id,
|
|
7490
|
+
workspaceName: input.workspace.name
|
|
7491
|
+
});
|
|
7242
7492
|
return "skipped";
|
|
7243
7493
|
}
|
|
7244
7494
|
const spinner = createOrgxSpinner("Routing");
|
|
@@ -7473,7 +7723,11 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7473
7723
|
const storedFirstValueInitiative = existingState?.firstValueInitiative?.workspaceId === input.workspace.id ? existingState.firstValueInitiative : void 0;
|
|
7474
7724
|
let effectiveInitiativeId = providedInitiativeId || storedDemoInitiative?.id || storedFirstValueInitiative?.id;
|
|
7475
7725
|
let firstValueInitiative = providedInitiativeId || storedDemoInitiative ? null : firstValueRecordToResult(storedFirstValueInitiative);
|
|
7476
|
-
|
|
7726
|
+
const firstInitiativeSkipped = hasSetupPromptSkip(
|
|
7727
|
+
input.workspace.id,
|
|
7728
|
+
"first_initiative"
|
|
7729
|
+
);
|
|
7730
|
+
if (!effectiveInitiativeId && !firstInitiativeSkipped) {
|
|
7477
7731
|
const firstInitiativeChoice = await selectPrompt({
|
|
7478
7732
|
initialValue: "yes",
|
|
7479
7733
|
message: `Create your first OrgX initiative in ${input.workspace.name}?`,
|
|
@@ -7530,10 +7784,20 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7530
7784
|
const message = error instanceof Error ? error.message : String(error);
|
|
7531
7785
|
console.log(` ${ICON.warn} ${pc3.yellow("initiative")} ${pc3.dim(message)}`);
|
|
7532
7786
|
}
|
|
7787
|
+
} else if (firstInitiativeChoice === "no") {
|
|
7788
|
+
recordSetupPromptSkip({
|
|
7789
|
+
promptKey: "first_initiative",
|
|
7790
|
+
workspaceId: input.workspace.id,
|
|
7791
|
+
workspaceName: input.workspace.name
|
|
7792
|
+
});
|
|
7533
7793
|
}
|
|
7534
7794
|
}
|
|
7535
7795
|
const hasOnboardingTask = existingState?.onboardingTask?.workspaceId === input.workspace.id;
|
|
7536
|
-
|
|
7796
|
+
const onboardingTaskSkipped = hasSetupPromptSkip(
|
|
7797
|
+
input.workspace.id,
|
|
7798
|
+
"onboarding_task"
|
|
7799
|
+
);
|
|
7800
|
+
if (!hasOnboardingTask && effectiveInitiativeId && !onboardingTaskSkipped) {
|
|
7537
7801
|
let shouldCreateOnboardingTask = firstValueInitiative !== null;
|
|
7538
7802
|
if (!shouldCreateOnboardingTask) {
|
|
7539
7803
|
const onboardingChoice = await selectPrompt({
|
|
@@ -7549,6 +7813,13 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7549
7813
|
return "cancelled";
|
|
7550
7814
|
}
|
|
7551
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
|
+
}
|
|
7552
7823
|
}
|
|
7553
7824
|
if (shouldCreateOnboardingTask) {
|
|
7554
7825
|
const spinner = createOrgxSpinner("Creating onboarding workstream and starter task");
|
|
@@ -7588,7 +7859,8 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7588
7859
|
}
|
|
7589
7860
|
const refreshedState = readWizardState();
|
|
7590
7861
|
const hasAgentRoster = refreshedState?.agentRoster?.workspaceId === input.workspace.id;
|
|
7591
|
-
|
|
7862
|
+
const agentRosterSkipped = hasSetupPromptSkip(input.workspace.id, "agent_roster");
|
|
7863
|
+
if (!hasAgentRoster && !agentRosterSkipped) {
|
|
7592
7864
|
const rosterChoice = await selectPrompt({
|
|
7593
7865
|
initialValue: "default",
|
|
7594
7866
|
message: `Set up an OrgX agent roster for ${input.workspace.name}?`,
|
|
@@ -7624,6 +7896,11 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7624
7896
|
);
|
|
7625
7897
|
} else {
|
|
7626
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
|
+
});
|
|
7627
7904
|
}
|
|
7628
7905
|
} else if (rosterChoice === "default") {
|
|
7629
7906
|
const roster = ensureDefaultAgentRoster(input.workspace);
|
|
@@ -7641,6 +7918,12 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
7641
7918
|
}
|
|
7642
7919
|
)
|
|
7643
7920
|
);
|
|
7921
|
+
} else if (rosterChoice === "no") {
|
|
7922
|
+
recordSetupPromptSkip({
|
|
7923
|
+
promptKey: "agent_roster",
|
|
7924
|
+
workspaceId: input.workspace.id,
|
|
7925
|
+
workspaceName: input.workspace.name
|
|
7926
|
+
});
|
|
7644
7927
|
}
|
|
7645
7928
|
}
|
|
7646
7929
|
return "configured";
|
|
@@ -7720,11 +8003,11 @@ async function maybeInstallOptionalCompanionPlugins(input) {
|
|
|
7720
8003
|
}
|
|
7721
8004
|
function printAuthStatus(status) {
|
|
7722
8005
|
if (!status.configured) {
|
|
7723
|
-
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`);
|
|
7724
8007
|
return;
|
|
7725
8008
|
}
|
|
7726
8009
|
const icon = status.ok ? ICON.ok : ICON.err;
|
|
7727
|
-
const state = status.ok ? pc3.green("
|
|
8010
|
+
const state = status.ok ? pc3.green("paired ") : status.skipped ? pc3.yellow("skipped ") : pc3.red("invalid ");
|
|
7728
8011
|
const via = pc3.dim(formatAuthSource(status.source));
|
|
7729
8012
|
console.log(` ${icon} ${state} ${pc3.bold(status.keyPrefix ?? "unknown")} ${via}`);
|
|
7730
8013
|
if (!status.ok && status.error) {
|
|
@@ -7796,13 +8079,16 @@ function printDoctorReport(report, assessment) {
|
|
|
7796
8079
|
async function main() {
|
|
7797
8080
|
const program = new Command();
|
|
7798
8081
|
program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
|
|
7799
|
-
const pkgVersion = true ? "0.1.
|
|
8082
|
+
const pkgVersion = true ? "0.1.25" : void 0;
|
|
7800
8083
|
program.version(pkgVersion ?? "unknown", "-V, --version");
|
|
7801
8084
|
program.hook("preAction", () => {
|
|
7802
8085
|
console.log(renderBanner(pkgVersion));
|
|
7803
8086
|
});
|
|
7804
|
-
program.command("setup").description("Add OrgX MCP configs, skills/rules, and companion plugins to detected tools.").option("--preset <name>", "run a setup bundle (currently: founder)").action(async (options) => {
|
|
8087
|
+
program.command("setup").description("Add OrgX MCP configs, skills/rules, and companion plugins to detected tools.").option("--preset <name>", "run a setup bundle (currently: founder)").option("--workspace", "choose or change the default workspace during setup").option("--daily-brief", "configure Daily Brief even if setup already handled it").option("--skip-daily-brief", "skip Daily Brief prompts and remember the skip").action(async (options) => {
|
|
7805
8088
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8089
|
+
if (options.dailyBrief && options.skipDailyBrief) {
|
|
8090
|
+
throw new Error("Use either --daily-brief or --skip-daily-brief, not both.");
|
|
8091
|
+
}
|
|
7806
8092
|
await safeTrackWizardTelemetry("wizard_started", {
|
|
7807
8093
|
command: "setup",
|
|
7808
8094
|
interactive,
|
|
@@ -7921,9 +8207,9 @@ async function main() {
|
|
|
7921
8207
|
console.log("");
|
|
7922
8208
|
if (interactive) {
|
|
7923
8209
|
const choice = await selectPrompt({
|
|
7924
|
-
message: "
|
|
8210
|
+
message: "Pair this terminal with your OrgX account to finish setup",
|
|
7925
8211
|
options: [
|
|
7926
|
-
{ value: "login", label: "Open browser to
|
|
8212
|
+
{ value: "login", label: "Open browser to pair", hint: "recommended" },
|
|
7927
8213
|
{ value: "skip", label: "Skip for now", hint: `run \`${getCmd()} auth login\` later` }
|
|
7928
8214
|
]
|
|
7929
8215
|
});
|
|
@@ -7935,19 +8221,19 @@ async function main() {
|
|
|
7935
8221
|
const loginOk = await runBrowserLogin({ telemetrySource: "browser_pairing" });
|
|
7936
8222
|
if (!loginOk) {
|
|
7937
8223
|
console.log(`
|
|
7938
|
-
${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")}`);
|
|
7939
8225
|
console.log(` ${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} auth login --api-key`)} ${pc3.dim("to paste a key directly")}`);
|
|
7940
8226
|
return;
|
|
7941
8227
|
}
|
|
7942
8228
|
resolvedAuth = await resolveOrgxAuth();
|
|
7943
8229
|
} else {
|
|
7944
8230
|
console.log(`
|
|
7945
|
-
${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")}`);
|
|
7946
8232
|
return;
|
|
7947
8233
|
}
|
|
7948
8234
|
} else {
|
|
7949
8235
|
console.log(
|
|
7950
|
-
` ${ICON.warn} ${pc3.yellow("
|
|
8236
|
+
` ${ICON.warn} ${pc3.yellow("Terminal not paired.")} Run ${pc3.cyan(`${getCmd()} auth login`)} to pair it.`
|
|
7951
8237
|
);
|
|
7952
8238
|
return;
|
|
7953
8239
|
}
|
|
@@ -7968,7 +8254,8 @@ async function main() {
|
|
|
7968
8254
|
text: textPrompt
|
|
7969
8255
|
},
|
|
7970
8256
|
{
|
|
7971
|
-
interactive
|
|
8257
|
+
interactive,
|
|
8258
|
+
skipIfConfigured: !options.workspace
|
|
7972
8259
|
}
|
|
7973
8260
|
);
|
|
7974
8261
|
if (workspaceSetup.status === "cancelled") {
|
|
@@ -8006,7 +8293,9 @@ async function main() {
|
|
|
8006
8293
|
console.log(` ${ICON.ok} ${pc3.green("workspace ")} ${pc3.bold(workspaceSetup.workspace.name)}`);
|
|
8007
8294
|
}
|
|
8008
8295
|
const briefResult = await runDailyBriefOnboarding({
|
|
8296
|
+
force: Boolean(options.dailyBrief),
|
|
8009
8297
|
interactive,
|
|
8298
|
+
skip: Boolean(options.skipDailyBrief),
|
|
8010
8299
|
workspace: resolvedWorkspace,
|
|
8011
8300
|
prompts: {
|
|
8012
8301
|
cancel: clack.cancel,
|
|
@@ -8018,6 +8307,8 @@ async function main() {
|
|
|
8018
8307
|
});
|
|
8019
8308
|
if (briefResult.status === "cancelled") {
|
|
8020
8309
|
console.log(` ${ICON.skip} ${pc3.dim(briefResult.message)}`);
|
|
8310
|
+
} else if (briefResult.status === "skipped_user") {
|
|
8311
|
+
console.log(` ${ICON.skip} ${pc3.dim(briefResult.message)}`);
|
|
8021
8312
|
} else if (briefResult.status === "completed") {
|
|
8022
8313
|
console.log(` ${ICON.ok} ${pc3.green("daily brief")} ${pc3.dim(briefResult.message)}`);
|
|
8023
8314
|
} else if (briefResult.status === "failed") {
|
|
@@ -8122,9 +8413,9 @@ async function main() {
|
|
|
8122
8413
|
has_base_url: false
|
|
8123
8414
|
});
|
|
8124
8415
|
const openclawResults = detectSurface("openclaw").detected ? await addSurface("openclaw") : [];
|
|
8125
|
-
spinner.succeed("OrgX account
|
|
8416
|
+
spinner.succeed("OrgX account paired");
|
|
8126
8417
|
await syncContinuityAfterAuth();
|
|
8127
|
-
console.log(` ${ICON.ok} ${pc3.green("
|
|
8418
|
+
console.log(` ${ICON.ok} ${pc3.green("paired ")} ${pc3.bold(stored.keyPrefix)} ${pc3.dim("browser sign-in")}`);
|
|
8128
8419
|
if (openclawResults.length > 0) {
|
|
8129
8420
|
console.log("");
|
|
8130
8421
|
printMutationResults(openclawResults);
|
|
@@ -8137,22 +8428,36 @@ async function main() {
|
|
|
8137
8428
|
return false;
|
|
8138
8429
|
}
|
|
8139
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
|
+
}
|
|
8140
8440
|
async function runBrowserLogin(opts = {}) {
|
|
8141
8441
|
const installationId = getOrCreateWizardInstallationId();
|
|
8442
|
+
const deviceName = opts.deviceName ?? hostname();
|
|
8142
8443
|
const spinner = createOrgxSpinner("Starting OrgX browser pairing");
|
|
8143
8444
|
spinner.start();
|
|
8144
8445
|
try {
|
|
8145
8446
|
const pairing = await startBrowserPairing({
|
|
8146
8447
|
installationId,
|
|
8147
8448
|
baseUrl: opts.baseUrl,
|
|
8148
|
-
deviceName
|
|
8449
|
+
deviceName,
|
|
8149
8450
|
platform: process.platform
|
|
8150
8451
|
});
|
|
8151
|
-
spinner.succeed("Browser pairing
|
|
8452
|
+
spinner.succeed("Browser pairing ready");
|
|
8152
8453
|
console.log(`
|
|
8153
|
-
${pc3.dim("Open this URL to
|
|
8454
|
+
${pc3.dim("Open this URL to approve terminal pairing:")}`);
|
|
8154
8455
|
console.log(` ${pc3.cyan(pairing.connectUrl)}
|
|
8155
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
|
+
);
|
|
8156
8461
|
if (opts.open !== false) {
|
|
8157
8462
|
const openResult = openBrowser(pairing.connectUrl);
|
|
8158
8463
|
if (!openResult.ok && openResult.error) {
|
|
@@ -8168,33 +8473,38 @@ async function main() {
|
|
|
8168
8473
|
pollToken: pairing.pollToken,
|
|
8169
8474
|
timeoutMs: (opts.timeout ?? 600) * 1e3
|
|
8170
8475
|
});
|
|
8171
|
-
spinner.text = "Verifying
|
|
8476
|
+
spinner.text = "Verifying paired account...";
|
|
8172
8477
|
const result = await verifyAndPersistAuth(ready.key, {
|
|
8173
8478
|
...opts.baseUrl !== void 0 ? { baseUrl: opts.baseUrl } : {},
|
|
8174
8479
|
...opts.telemetrySource ? { telemetrySource: opts.telemetrySource } : {}
|
|
8175
8480
|
});
|
|
8176
8481
|
if (!("stored" in result)) {
|
|
8177
|
-
spinner.fail("Pairing completed but
|
|
8482
|
+
spinner.fail("Pairing completed but OrgX rejected the key");
|
|
8178
8483
|
console.log(` ${pc3.red(result.verification.error ?? `HTTP ${result.verification.status ?? "error"}`)}`);
|
|
8179
8484
|
console.log(` ${pc3.dim("The browser flow finished, but OrgX rejected the key. Try again or check your account at useorgx.com.")}`);
|
|
8180
8485
|
return false;
|
|
8181
8486
|
}
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
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) {
|
|
8187
8496
|
console.log(pc3.dim(`Pairing ack failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
8188
|
-
}
|
|
8189
|
-
spinner.succeed("OrgX account
|
|
8497
|
+
}
|
|
8498
|
+
spinner.succeed("OrgX account paired");
|
|
8190
8499
|
await syncContinuityAfterAuth({
|
|
8191
8500
|
executionMode: ready.executionMode,
|
|
8192
8501
|
workspaceName: ready.workspaceName
|
|
8193
8502
|
});
|
|
8194
|
-
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")}`);
|
|
8195
8504
|
if (ready.workspaceName) {
|
|
8196
8505
|
console.log(` ${ICON.ok} ${pc3.green("workspace ")} ${pc3.bold(ready.workspaceName)}`);
|
|
8197
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))}`);
|
|
8198
8508
|
if (result.openclawResults.length > 0) {
|
|
8199
8509
|
console.log("");
|
|
8200
8510
|
printMutationResults(result.openclawResults);
|
|
@@ -8207,8 +8517,8 @@ async function main() {
|
|
|
8207
8517
|
return false;
|
|
8208
8518
|
}
|
|
8209
8519
|
}
|
|
8210
|
-
const auth = program.command("auth").description("
|
|
8211
|
-
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 () => {
|
|
8212
8522
|
const spinner = createOrgxSpinner("Checking OrgX auth");
|
|
8213
8523
|
spinner.start();
|
|
8214
8524
|
const status = await checkOrgxAuth();
|
|
@@ -8216,7 +8526,7 @@ async function main() {
|
|
|
8216
8526
|
console.log(pc3.dim(" account"));
|
|
8217
8527
|
printAuthStatus(status);
|
|
8218
8528
|
});
|
|
8219
|
-
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) => {
|
|
8220
8530
|
if (options.apiKey) {
|
|
8221
8531
|
const spinner = createOrgxSpinner("Verifying OrgX API key");
|
|
8222
8532
|
spinner.start();
|
|
@@ -8229,9 +8539,9 @@ async function main() {
|
|
|
8229
8539
|
printAuthStatus(result.verification);
|
|
8230
8540
|
return;
|
|
8231
8541
|
}
|
|
8232
|
-
spinner.succeed("OrgX account
|
|
8542
|
+
spinner.succeed("OrgX account paired");
|
|
8233
8543
|
await syncContinuityAfterAuth();
|
|
8234
|
-
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")}`);
|
|
8235
8545
|
if (result.openclawResults.length > 0) {
|
|
8236
8546
|
console.log("");
|
|
8237
8547
|
printMutationResults(result.openclawResults);
|
|
@@ -8254,7 +8564,7 @@ async function main() {
|
|
|
8254
8564
|
timeout: options.timeout
|
|
8255
8565
|
});
|
|
8256
8566
|
if (!pkceOk) {
|
|
8257
|
-
console.log(pc3.dim("\n
|
|
8567
|
+
console.log(pc3.dim("\n Browser sign-in did not finish. Opening the terminal pairing fallback..."));
|
|
8258
8568
|
await runBrowserLogin({
|
|
8259
8569
|
...options.baseUrl !== void 0 ? { baseUrl: options.baseUrl } : {},
|
|
8260
8570
|
...options.deviceName !== void 0 ? { deviceName: options.deviceName } : {},
|
|
@@ -8276,9 +8586,9 @@ async function main() {
|
|
|
8276
8586
|
printAuthStatus(result.verification);
|
|
8277
8587
|
return;
|
|
8278
8588
|
}
|
|
8279
|
-
spinner.succeed("OrgX account
|
|
8589
|
+
spinner.succeed("OrgX account paired");
|
|
8280
8590
|
await syncContinuityAfterAuth();
|
|
8281
|
-
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")}`);
|
|
8282
8592
|
if (result.openclawResults.length > 0) {
|
|
8283
8593
|
console.log("");
|
|
8284
8594
|
printMutationResults(result.openclawResults);
|