@useorgx/wizard 0.1.12 → 0.1.13

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 CHANGED
@@ -22,7 +22,7 @@ The wizard modifies local tool configuration only. Depending on the command, it
22
22
 
23
23
  ## Commands
24
24
 
25
- - `setup` adds OrgX MCP configs, standalone skills/rules, and companion plugins to detected AI tools. When OrgX auth is available in an interactive shell, it also guides workspace selection or creation, optional onboarding extras, and optional companion plugin installs for detected Cursor, Claude Code, Codex, and OpenClaw hosts. The founder preset preplans plugin installs before it writes standalone skills so plugin-backed hosts do not get duplicate standalone assets in the same run.
25
+ - `setup` adds OrgX MCP configs, standalone skills/rules, and companion plugins to detected AI tools. When OrgX auth is available in an interactive shell, it guides workspace selection or creation, can create the user's first live OrgX initiative, creates a starter onboarding task under that initiative, and prints a handoff prompt for the configured AI tool of choice. The founder preset preplans plugin installs before it writes standalone skills so plugin-backed hosts do not get duplicate standalone assets in the same run.
26
26
  - `surface list` shows supported surfaces and current status.
27
27
  - `surface add <name>` patches a specific surface.
28
28
  - `surface remove <name>` removes OrgX-managed config from a specific surface.
@@ -60,6 +60,8 @@ The wizard modifies local tool configuration only. Depending on the command, it
60
60
  ## Workspace Bootstrap
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
+ - 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
+ - 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.
63
65
  - `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.
64
66
  - `wizard workspace list` lists all accessible workspaces.
65
67
  - `wizard workspace create "Founders" --description "Initial OrgX workspace"` creates a new workspace through `POST /api/entities`.
package/dist/cli.js CHANGED
@@ -519,9 +519,6 @@ function normalizeOrgxBaseUrl(raw) {
519
519
  }
520
520
  function buildOrgxApiUrl(path, baseUrl) {
521
521
  const parsedBase = new URL(normalizeOrgxBaseUrl(baseUrl));
522
- if (parsedBase.protocol === "https:" && normalizeHost(parsedBase.hostname) === "useorgx.com") {
523
- parsedBase.hostname = "www.useorgx.com";
524
- }
525
522
  const normalizedBase = parsedBase.toString().replace(/\/+$/, "");
526
523
  const apiBase = normalizedBase.endsWith("/api") ? normalizedBase : `${normalizedBase}/api`;
527
524
  const normalizedPath = path.startsWith("/") ? path : `/${path}`;
@@ -930,6 +927,24 @@ function parseDemoInitiative(value) {
930
927
  ...isNonEmptyString2(record.workspaceName) ? { workspaceName: record.workspaceName.trim() } : {}
931
928
  };
932
929
  }
930
+ function parseFirstValueInitiative(value) {
931
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
932
+ return void 0;
933
+ }
934
+ const record = value;
935
+ if (!isNonEmptyString2(record.id) || !isNonEmptyString2(record.title) || !isNonEmptyString2(record.liveUrl) || !isNonEmptyString2(record.createdAt)) {
936
+ return void 0;
937
+ }
938
+ return {
939
+ createdAt: record.createdAt.trim(),
940
+ id: record.id.trim(),
941
+ liveUrl: record.liveUrl.trim(),
942
+ ...isNonEmptyString2(record.summary) ? { summary: record.summary.trim() } : {},
943
+ title: record.title.trim(),
944
+ ...isNonEmptyString2(record.workspaceId) ? { workspaceId: record.workspaceId.trim() } : {},
945
+ ...isNonEmptyString2(record.workspaceName) ? { workspaceName: record.workspaceName.trim() } : {}
946
+ };
947
+ }
933
948
  function parseOnboardingTask(value) {
934
949
  if (!value || typeof value !== "object" || Array.isArray(value)) {
935
950
  return void 0;
@@ -1026,6 +1041,7 @@ function sanitizeWizardStateRecord(record) {
1026
1041
  const continuity = parseContinuityDefaults(record.continuity);
1027
1042
  const agentRoster = parseAgentRoster(record.agentRoster);
1028
1043
  const demoInitiative = parseDemoInitiative(record.demoInitiative);
1044
+ const firstValueInitiative = parseFirstValueInitiative(record.firstValueInitiative);
1029
1045
  const onboardingTask = parseOnboardingTask(record.onboardingTask);
1030
1046
  const skillFiles = parseSkillFiles(record.skillFiles);
1031
1047
  return {
@@ -1035,6 +1051,7 @@ function sanitizeWizardStateRecord(record) {
1035
1051
  ...continuity ? { continuity } : {},
1036
1052
  ...agentRoster ? { agentRoster } : {},
1037
1053
  ...demoInitiative ? { demoInitiative } : {},
1054
+ ...firstValueInitiative ? { firstValueInitiative } : {},
1038
1055
  ...onboardingTask ? { onboardingTask } : {},
1039
1056
  ...skillFiles ? { skillFiles } : {}
1040
1057
  };
@@ -1055,6 +1072,10 @@ function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
1055
1072
  if (agentRoster !== void 0) state.agentRoster = agentRoster;
1056
1073
  const demoInitiative = parseDemoInitiative(parsed.demoInitiative);
1057
1074
  if (demoInitiative !== void 0) state.demoInitiative = demoInitiative;
1075
+ const firstValueInitiative = parseFirstValueInitiative(parsed.firstValueInitiative);
1076
+ if (firstValueInitiative !== void 0) {
1077
+ state.firstValueInitiative = firstValueInitiative;
1078
+ }
1058
1079
  const onboardingTask = parseOnboardingTask(parsed.onboardingTask);
1059
1080
  if (onboardingTask !== void 0) state.onboardingTask = onboardingTask;
1060
1081
  const skillFiles = parseSkillFiles(parsed.skillFiles);
@@ -2706,6 +2727,8 @@ var ONBOARDING_TASK_TITLE = "Complete OrgX onboarding";
2706
2727
  var ONBOARDING_TASK_SUMMARY = "Starter onboarding task created by @useorgx/wizard so the first workspace has a clear follow-up after setup.";
2707
2728
  var ONBOARDING_WORKSTREAM_TITLE = "OrgX onboarding";
2708
2729
  var ONBOARDING_WORKSTREAM_SUMMARY = "Starter onboarding workstream created by @useorgx/wizard so the first workspace has a home for setup follow-up tasks.";
2730
+ var FIRST_VALUE_INITIATIVE_TITLE = "Make OrgX useful on this machine";
2731
+ var FIRST_VALUE_INITIATIVE_SUMMARY = "First initiative created by @useorgx/wizard so setup ends with a live workspace, an onboarding workstream, and a clean handoff into the user's configured AI tools.";
2709
2732
  function parseResponseBody3(text2) {
2710
2733
  if (!text2) {
2711
2734
  return null;
@@ -2827,6 +2850,17 @@ function toOnboardingTaskRecord(task, workspace, options = {}) {
2827
2850
  workspaceName: workspace.name
2828
2851
  };
2829
2852
  }
2853
+ function toFirstValueInitiativeRecord(initiative, liveUrl, workspace) {
2854
+ return {
2855
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2856
+ id: initiative.id,
2857
+ liveUrl,
2858
+ ...initiative.summary ? { summary: initiative.summary } : {},
2859
+ title: initiative.title,
2860
+ workspaceId: workspace.id,
2861
+ workspaceName: workspace.name
2862
+ };
2863
+ }
2830
2864
  async function requireOrgxAuth2(options = {}) {
2831
2865
  const auth = await resolveOrgxAuth(options);
2832
2866
  if (!auth) {
@@ -2879,9 +2913,6 @@ async function updateEntity(type, id, body, parse2, options = {}) {
2879
2913
  }
2880
2914
  function buildLiveUrl(baseUrl, initiativeId) {
2881
2915
  const parsed = new URL(normalizeOrgxBaseUrl(baseUrl));
2882
- if (parsed.protocol === "https:" && parsed.hostname === "useorgx.com") {
2883
- parsed.hostname = "www.useorgx.com";
2884
- }
2885
2916
  parsed.pathname = `/live/${initiativeId}`;
2886
2917
  parsed.search = "";
2887
2918
  parsed.hash = "";
@@ -2992,6 +3023,43 @@ async function ensureFounderDemoInitiative(workspace, options = {}) {
2992
3023
  liveUrl
2993
3024
  };
2994
3025
  }
3026
+ async function ensureFirstValueInitiative(workspace, options = {}) {
3027
+ const existingRecord = readWizardState(options.statePath)?.firstValueInitiative;
3028
+ const matchingRecord = existingRecord?.workspaceId === workspace.id ? existingRecord : void 0;
3029
+ const auth = await requireOrgxAuth2(options);
3030
+ if (matchingRecord) {
3031
+ return {
3032
+ created: false,
3033
+ initiative: {
3034
+ id: matchingRecord.id,
3035
+ title: matchingRecord.title,
3036
+ ...matchingRecord.summary ? { summary: matchingRecord.summary } : {}
3037
+ },
3038
+ liveUrl: matchingRecord.liveUrl || buildLiveUrl(auth.baseUrl, matchingRecord.id)
3039
+ };
3040
+ }
3041
+ const initiative = await createInitiative(
3042
+ {
3043
+ title: options.title?.trim() || FIRST_VALUE_INITIATIVE_TITLE,
3044
+ summary: options.summary?.trim() || FIRST_VALUE_INITIATIVE_SUMMARY,
3045
+ workspaceId: workspace.id
3046
+ },
3047
+ options
3048
+ );
3049
+ const liveUrl = buildLiveUrl(auth.baseUrl, initiative.id);
3050
+ updateWizardState(
3051
+ (current) => ({
3052
+ ...current,
3053
+ firstValueInitiative: toFirstValueInitiativeRecord(initiative, liveUrl, workspace)
3054
+ }),
3055
+ options.statePath
3056
+ );
3057
+ return {
3058
+ created: true,
3059
+ initiative,
3060
+ liveUrl
3061
+ };
3062
+ }
2995
3063
  async function ensureOnboardingTask(workspace, options = {}) {
2996
3064
  const existingRecord = readWizardState(options.statePath)?.onboardingTask;
2997
3065
  if (existingRecord?.workspaceId === workspace.id) {
@@ -4889,6 +4957,15 @@ function buildFounderDemoTelemetryProperties(result, base = {}) {
4889
4957
  base
4890
4958
  );
4891
4959
  }
4960
+ function buildFirstValueInitiativeTelemetryProperties(result, base = {}) {
4961
+ return withBaseProperties(
4962
+ {
4963
+ created: result.created,
4964
+ has_live_url: Boolean(result.liveUrl)
4965
+ },
4966
+ base
4967
+ );
4968
+ }
4892
4969
  function buildDoctorTelemetryProperties(report, assessment, verification, base = {}) {
4893
4970
  const errorCount = assessment.issues.filter((issue) => issue.level === "error").length;
4894
4971
  const warningCount = assessment.issues.filter((issue) => issue.level === "warning").length;
@@ -5181,6 +5258,41 @@ function printWorkspaceSetupResult(result) {
5181
5258
  console.log(` ${ICON.skip} ${pc3.dim(result.message)}`);
5182
5259
  }
5183
5260
  }
5261
+ function printSetupScopeNote() {
5262
+ console.log(pc3.dim(" setup updates your AI tools with:"));
5263
+ console.log(` ${ICON.skip} ${pc3.dim("MCP configs for local and cloud OrgX access")}`);
5264
+ console.log(` ${ICON.skip} ${pc3.dim("OrgX agent skills, rules, prompts, commands, and hooks")}`);
5265
+ console.log(` ${ICON.skip} ${pc3.dim("companion plugins where your editor supports them")}`);
5266
+ }
5267
+ function printFirstValueHandoff(input) {
5268
+ const cmd = getCmd();
5269
+ console.log("");
5270
+ console.log(pc3.bold("first OrgX handoff"));
5271
+ console.log(
5272
+ ` ${input.initiative.created ? pc3.green("created") : pc3.yellow("ready")} ${pc3.bold(input.initiative.initiative.title)}`
5273
+ );
5274
+ console.log(` live: ${input.initiative.liveUrl}`);
5275
+ console.log(
5276
+ ` ${pc3.dim("ask your AI tool:")} ${pc3.cyan(
5277
+ `Use OrgX to continue "${input.initiative.initiative.title}" in ${input.workspace.name}. Show the next action, then start with the onboarding task.`
5278
+ )}`
5279
+ );
5280
+ console.log(` ${pc3.dim("later:")} ${pc3.cyan(`${cmd} doctor`)} ${pc3.dim("checks tool wiring")}`);
5281
+ }
5282
+ function firstValueRecordToResult(record) {
5283
+ if (!record) {
5284
+ return null;
5285
+ }
5286
+ return {
5287
+ created: false,
5288
+ initiative: {
5289
+ id: record.id,
5290
+ title: record.title,
5291
+ ...record.summary ? { summary: record.summary } : {}
5292
+ },
5293
+ liveUrl: record.liveUrl
5294
+ };
5295
+ }
5184
5296
  function printFounderPresetResult(result) {
5185
5297
  printMutationResults(result.surfaceResults);
5186
5298
  console.log("");
@@ -5221,7 +5333,7 @@ async function textPrompt(input) {
5221
5333
  }
5222
5334
  async function multiselectPrompt(input) {
5223
5335
  const promptInput = {
5224
- message: `${input.message} ${pc3.dim("Space selects items; Enter continues.")}`,
5336
+ message: `${input.message} ${pc3.dim("Space to select, Enter to continue. Defaults are preselected.")}`,
5225
5337
  options: input.options,
5226
5338
  ...input.initialValues ? { initialValues: input.initialValues } : {},
5227
5339
  ...input.required !== void 0 ? { required: input.required } : {}
@@ -5328,25 +5440,96 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
5328
5440
  return "skipped";
5329
5441
  }
5330
5442
  const existingState = readWizardState();
5331
- const effectiveInitiativeId = input.initiativeId?.trim() || (existingState?.demoInitiative?.workspaceId === input.workspace.id ? existingState.demoInitiative.id : void 0);
5332
- const hasOnboardingTask = existingState?.onboardingTask?.workspaceId === input.workspace.id;
5333
- if (!hasOnboardingTask && effectiveInitiativeId) {
5334
- const onboardingChoice = await selectPrompt({
5335
- message: `Create a starter onboarding task for ${input.workspace.name}?`,
5443
+ const providedInitiativeId = input.initiativeId?.trim();
5444
+ const storedDemoInitiative = existingState?.demoInitiative?.workspaceId === input.workspace.id ? existingState.demoInitiative : void 0;
5445
+ const storedFirstValueInitiative = existingState?.firstValueInitiative?.workspaceId === input.workspace.id ? existingState.firstValueInitiative : void 0;
5446
+ let effectiveInitiativeId = providedInitiativeId || storedDemoInitiative?.id || storedFirstValueInitiative?.id;
5447
+ let firstValueInitiative = providedInitiativeId || storedDemoInitiative ? null : firstValueRecordToResult(storedFirstValueInitiative);
5448
+ if (!effectiveInitiativeId) {
5449
+ const firstInitiativeChoice = await selectPrompt({
5450
+ initialValue: "yes",
5451
+ message: `Create your first OrgX initiative in ${input.workspace.name}?`,
5336
5452
  options: [
5337
- { value: "yes", label: "Create onboarding task", hint: "recommended" },
5338
- { value: "no", label: "Skip task creation" }
5453
+ {
5454
+ value: "yes",
5455
+ label: "Create first initiative",
5456
+ hint: "recommended; gives setup a live next step"
5457
+ },
5458
+ { value: "no", label: "Skip initiative creation" }
5339
5459
  ]
5340
5460
  });
5341
- if (clack.isCancel(onboardingChoice)) {
5461
+ if (clack.isCancel(firstInitiativeChoice)) {
5342
5462
  clack.cancel("Setup cancelled.");
5343
5463
  return "cancelled";
5344
5464
  }
5345
- if (onboardingChoice === "yes") {
5465
+ if (firstInitiativeChoice === "yes") {
5466
+ const title = await textPrompt({
5467
+ initialValue: FIRST_VALUE_INITIATIVE_TITLE,
5468
+ message: "What should OrgX help you move forward first?",
5469
+ validate: (value) => {
5470
+ if (!value || value.trim().length === 0) {
5471
+ return "Enter an initiative title.";
5472
+ }
5473
+ return void 0;
5474
+ }
5475
+ });
5476
+ if (clack.isCancel(title)) {
5477
+ clack.cancel("Setup cancelled.");
5478
+ return "cancelled";
5479
+ }
5480
+ const spinner = createOrgxSpinner("Creating your first OrgX initiative and live handoff");
5481
+ spinner.start();
5482
+ try {
5483
+ firstValueInitiative = await ensureFirstValueInitiative(input.workspace, {
5484
+ title: String(title)
5485
+ });
5486
+ spinner.succeed(
5487
+ firstValueInitiative.created ? "First OrgX initiative created" : "First OrgX initiative ready"
5488
+ );
5489
+ effectiveInitiativeId = firstValueInitiative.initiative.id;
5490
+ await safeTrackWizardTelemetry(
5491
+ "first_value_initiative_ready",
5492
+ buildFirstValueInitiativeTelemetryProperties(
5493
+ firstValueInitiative,
5494
+ {
5495
+ command: input.telemetry?.command ?? "setup",
5496
+ ...input.telemetry?.preset ? { preset: input.telemetry.preset } : {}
5497
+ }
5498
+ )
5499
+ );
5500
+ } catch (error) {
5501
+ spinner.fail("First OrgX initiative was not created");
5502
+ const message = error instanceof Error ? error.message : String(error);
5503
+ console.log(` ${ICON.warn} ${pc3.yellow("initiative")} ${pc3.dim(message)}`);
5504
+ }
5505
+ }
5506
+ }
5507
+ const hasOnboardingTask = existingState?.onboardingTask?.workspaceId === input.workspace.id;
5508
+ if (!hasOnboardingTask && effectiveInitiativeId) {
5509
+ let shouldCreateOnboardingTask = firstValueInitiative !== null;
5510
+ if (!shouldCreateOnboardingTask) {
5511
+ const onboardingChoice = await selectPrompt({
5512
+ initialValue: "yes",
5513
+ message: `Create a starter onboarding task for ${input.workspace.name}?`,
5514
+ options: [
5515
+ { value: "yes", label: "Create onboarding task", hint: "recommended" },
5516
+ { value: "no", label: "Skip task creation" }
5517
+ ]
5518
+ });
5519
+ if (clack.isCancel(onboardingChoice)) {
5520
+ clack.cancel("Setup cancelled.");
5521
+ return "cancelled";
5522
+ }
5523
+ shouldCreateOnboardingTask = onboardingChoice === "yes";
5524
+ }
5525
+ if (shouldCreateOnboardingTask) {
5526
+ const spinner = createOrgxSpinner("Creating onboarding workstream and starter task");
5527
+ spinner.start();
5346
5528
  try {
5347
5529
  const task = await ensureOnboardingTask(input.workspace, {
5348
5530
  initiativeId: effectiveInitiativeId
5349
5531
  });
5532
+ spinner.succeed("Onboarding workstream and starter task ready");
5350
5533
  console.log(` ${ICON.ok} ${pc3.green("onboarding")} ${pc3.bold(task.title)}`);
5351
5534
  await safeTrackWizardTelemetry(
5352
5535
  "onboarding_task_created",
@@ -5363,11 +5546,18 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
5363
5546
  )
5364
5547
  );
5365
5548
  } catch (error) {
5549
+ spinner.fail("Onboarding task was not created");
5366
5550
  const message = error instanceof Error ? error.message : String(error);
5367
5551
  console.log(` ${ICON.warn} ${pc3.yellow("onboarding")} ${pc3.dim(message)}`);
5368
5552
  }
5369
5553
  }
5370
5554
  }
5555
+ if (firstValueInitiative) {
5556
+ printFirstValueHandoff({
5557
+ initiative: firstValueInitiative,
5558
+ workspace: input.workspace
5559
+ });
5560
+ }
5371
5561
  const refreshedState = readWizardState();
5372
5562
  const hasAgentRoster = refreshedState?.agentRoster?.workspaceId === input.workspace.id;
5373
5563
  if (!hasAgentRoster) {
@@ -5578,7 +5768,7 @@ function printDoctorReport(report, assessment) {
5578
5768
  async function main() {
5579
5769
  const program = new Command();
5580
5770
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
5581
- const pkgVersion = true ? "0.1.12" : void 0;
5771
+ const pkgVersion = true ? "0.1.13" : void 0;
5582
5772
  program.version(pkgVersion ?? "unknown", "-V, --version");
5583
5773
  program.hook("preAction", () => {
5584
5774
  console.log(renderBanner(pkgVersion));
@@ -5590,6 +5780,8 @@ async function main() {
5590
5780
  interactive,
5591
5781
  preset: options.preset ?? "standard"
5592
5782
  });
5783
+ printSetupScopeNote();
5784
+ console.log("");
5593
5785
  if (options.preset) {
5594
5786
  if (options.preset !== "founder") {
5595
5787
  throw new Error(`Unknown setup preset '${options.preset}'. Supported presets: founder.`);