@useorgx/wizard 0.1.46 → 0.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +400 -552
- package/dist/cli.js.map +1 -1
- package/package.json +10 -9
package/dist/cli.js
CHANGED
|
@@ -508,6 +508,31 @@ async function clearWizardAuth(authPath = ORGX_WIZARD_AUTH_PATH, options = {}) {
|
|
|
508
508
|
return secretRemoved || fileRemoved;
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
+
// src/lib/network.ts
|
|
512
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 12e3;
|
|
513
|
+
function isTimeoutError(error) {
|
|
514
|
+
if (!(error instanceof Error)) return false;
|
|
515
|
+
if (error.name === "TimeoutError" || error.name === "AbortError") return true;
|
|
516
|
+
const message = error.message.toLowerCase();
|
|
517
|
+
return message.includes("aborted due to timeout") || message.includes("operation was aborted");
|
|
518
|
+
}
|
|
519
|
+
async function fetchWithRetry(url, init, options = {}) {
|
|
520
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
521
|
+
const retries = options.retries ?? 1;
|
|
522
|
+
let lastError;
|
|
523
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
524
|
+
try {
|
|
525
|
+
return await fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
526
|
+
} catch (error) {
|
|
527
|
+
lastError = error;
|
|
528
|
+
if (!isTimeoutError(error) || attempt === retries) {
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
throw lastError;
|
|
534
|
+
}
|
|
535
|
+
|
|
511
536
|
// src/lib/auth.ts
|
|
512
537
|
function normalizeHost(value) {
|
|
513
538
|
return value.trim().toLowerCase().replace(/^\[|\]$/g, "");
|
|
@@ -652,14 +677,13 @@ async function parseResponseBody(response) {
|
|
|
652
677
|
async function verifyOrgxAuth(auth) {
|
|
653
678
|
const url = buildOrgxApiUrl("/client/sync", auth.baseUrl);
|
|
654
679
|
try {
|
|
655
|
-
const response = await
|
|
680
|
+
const response = await fetchWithRetry(url, {
|
|
656
681
|
method: "POST",
|
|
657
682
|
headers: {
|
|
658
683
|
Authorization: `Bearer ${auth.apiKey}`,
|
|
659
684
|
"Content-Type": "application/json"
|
|
660
685
|
},
|
|
661
|
-
body: "{}"
|
|
662
|
-
signal: AbortSignal.timeout(7e3)
|
|
686
|
+
body: "{}"
|
|
663
687
|
});
|
|
664
688
|
const data = await parseResponseBody(response);
|
|
665
689
|
return {
|
|
@@ -1177,30 +1201,6 @@ function parseContinuityDefaults(value) {
|
|
|
1177
1201
|
}
|
|
1178
1202
|
return Object.keys(parsed).length > 0 ? parsed : void 0;
|
|
1179
1203
|
}
|
|
1180
|
-
function parseDemoInitiative(value) {
|
|
1181
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1182
|
-
return void 0;
|
|
1183
|
-
}
|
|
1184
|
-
const record = value;
|
|
1185
|
-
if (!isNonEmptyString2(record.id) || !isNonEmptyString2(record.title) || !isNonEmptyString2(record.liveUrl) || !isNonEmptyString2(record.createdAt)) {
|
|
1186
|
-
return void 0;
|
|
1187
|
-
}
|
|
1188
|
-
return {
|
|
1189
|
-
createdAt: record.createdAt.trim(),
|
|
1190
|
-
...isNonEmptyString2(record.artifactId) ? { artifactId: record.artifactId.trim() } : {},
|
|
1191
|
-
...isNonEmptyString2(record.artifactName) ? { artifactName: record.artifactName.trim() } : {},
|
|
1192
|
-
...isNonEmptyString2(record.artifactType) ? { artifactType: record.artifactType.trim() } : {},
|
|
1193
|
-
...isNonEmptyString2(record.artifactUrl) ? { artifactUrl: record.artifactUrl.trim() } : {},
|
|
1194
|
-
...isNonEmptyString2(record.decisionId) ? { decisionId: record.decisionId.trim() } : {},
|
|
1195
|
-
...isNonEmptyString2(record.decisionStatus) ? { decisionStatus: record.decisionStatus.trim() } : {},
|
|
1196
|
-
...isNonEmptyString2(record.decisionTitle) ? { decisionTitle: record.decisionTitle.trim() } : {},
|
|
1197
|
-
id: record.id.trim(),
|
|
1198
|
-
liveUrl: record.liveUrl.trim(),
|
|
1199
|
-
title: record.title.trim(),
|
|
1200
|
-
...isNonEmptyString2(record.workspaceId) ? { workspaceId: record.workspaceId.trim() } : {},
|
|
1201
|
-
...isNonEmptyString2(record.workspaceName) ? { workspaceName: record.workspaceName.trim() } : {}
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
1204
|
function parseFirstValueInitiative(value) {
|
|
1205
1205
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1206
1206
|
return void 0;
|
|
@@ -1421,7 +1421,6 @@ function createWizardState(now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
|
1421
1421
|
function sanitizeWizardStateRecord(record) {
|
|
1422
1422
|
const continuity = parseContinuityDefaults(record.continuity);
|
|
1423
1423
|
const agentRoster = parseAgentRoster(record.agentRoster);
|
|
1424
|
-
const demoInitiative = parseDemoInitiative(record.demoInitiative);
|
|
1425
1424
|
const firstValueInitiative = parseFirstValueInitiative(record.firstValueInitiative);
|
|
1426
1425
|
const onboardingTask = parseOnboardingTask(record.onboardingTask);
|
|
1427
1426
|
const skillFiles = parseSkillFiles(record.skillFiles);
|
|
@@ -1434,7 +1433,6 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1434
1433
|
updatedAt: record.updatedAt.trim(),
|
|
1435
1434
|
...continuity ? { continuity } : {},
|
|
1436
1435
|
...agentRoster ? { agentRoster } : {},
|
|
1437
|
-
...demoInitiative ? { demoInitiative } : {},
|
|
1438
1436
|
...firstValueInitiative ? { firstValueInitiative } : {},
|
|
1439
1437
|
...onboardingTask ? { onboardingTask } : {},
|
|
1440
1438
|
...skillFiles ? { skillFiles } : {},
|
|
@@ -1457,8 +1455,6 @@ function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
|
1457
1455
|
if (continuity !== void 0) state.continuity = continuity;
|
|
1458
1456
|
const agentRoster = parseAgentRoster(parsed.agentRoster);
|
|
1459
1457
|
if (agentRoster !== void 0) state.agentRoster = agentRoster;
|
|
1460
|
-
const demoInitiative = parseDemoInitiative(parsed.demoInitiative);
|
|
1461
|
-
if (demoInitiative !== void 0) state.demoInitiative = demoInitiative;
|
|
1462
1458
|
const firstValueInitiative = parseFirstValueInitiative(parsed.firstValueInitiative);
|
|
1463
1459
|
if (firstValueInitiative !== void 0) {
|
|
1464
1460
|
state.firstValueInitiative = firstValueInitiative;
|
|
@@ -1949,12 +1945,11 @@ function formatHttpError(status, body) {
|
|
|
1949
1945
|
async function listWorkspaces(options = {}) {
|
|
1950
1946
|
const auth = await requireOrgxAuth(options);
|
|
1951
1947
|
const url = buildOrgxApiUrl("/entities?type=workspace&limit=100", auth.baseUrl);
|
|
1952
|
-
const response = await
|
|
1948
|
+
const response = await fetchWithRetry(url, {
|
|
1953
1949
|
method: "GET",
|
|
1954
1950
|
headers: {
|
|
1955
1951
|
Authorization: `Bearer ${auth.apiKey}`
|
|
1956
|
-
}
|
|
1957
|
-
signal: AbortSignal.timeout(7e3)
|
|
1952
|
+
}
|
|
1958
1953
|
});
|
|
1959
1954
|
const body = await parseResponseBody2(response);
|
|
1960
1955
|
if (!response.ok) {
|
|
@@ -1965,12 +1960,11 @@ async function listWorkspaces(options = {}) {
|
|
|
1965
1960
|
async function getCurrentWorkspace(options = {}) {
|
|
1966
1961
|
const auth = await requireOrgxAuth(options);
|
|
1967
1962
|
const url = buildOrgxApiUrl("/v1/workspaces/current", auth.baseUrl);
|
|
1968
|
-
const response = await
|
|
1963
|
+
const response = await fetchWithRetry(url, {
|
|
1969
1964
|
method: "GET",
|
|
1970
1965
|
headers: {
|
|
1971
1966
|
Authorization: `Bearer ${auth.apiKey}`
|
|
1972
|
-
}
|
|
1973
|
-
signal: AbortSignal.timeout(7e3)
|
|
1967
|
+
}
|
|
1974
1968
|
});
|
|
1975
1969
|
const body = await parseResponseBody2(response);
|
|
1976
1970
|
if (response.ok) {
|
|
@@ -4594,15 +4588,17 @@ function skippedOpenClawHealth() {
|
|
|
4594
4588
|
details: []
|
|
4595
4589
|
};
|
|
4596
4590
|
}
|
|
4597
|
-
async function runDoctor() {
|
|
4591
|
+
async function runDoctor(options = {}) {
|
|
4598
4592
|
const surfaces = listSurfaceStatuses();
|
|
4599
4593
|
const openclawSurface = surfaces.find((surface) => surface.name === "openclaw");
|
|
4600
|
-
const auth = await
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4594
|
+
const [auth, hostedMcp, hostedMcpTool, npmRegistry, workspace, openclaw] = await Promise.all([
|
|
4595
|
+
checkOrgxAuth(),
|
|
4596
|
+
checkHostedMcpHealth(),
|
|
4597
|
+
checkHostedMcpToolAccess(),
|
|
4598
|
+
checkNpmRegistryHealth(),
|
|
4599
|
+
options.cachedWorkspace ? Promise.resolve(options.cachedWorkspace) : checkWorkspaceConnectivity(),
|
|
4600
|
+
openclawSurface?.detected ? checkOpenClawHealth(openclawSurface.path) : Promise.resolve(skippedOpenClawHealth())
|
|
4601
|
+
]);
|
|
4606
4602
|
return { surfaces, auth, hostedMcp, hostedMcpTool, npmRegistry, workspace, openclaw };
|
|
4607
4603
|
}
|
|
4608
4604
|
function assessDoctorReport(report) {
|
|
@@ -4745,405 +4741,6 @@ function persistContinuityDefaults(seed = {}, statePath) {
|
|
|
4745
4741
|
);
|
|
4746
4742
|
}
|
|
4747
4743
|
|
|
4748
|
-
// src/lib/initiatives.ts
|
|
4749
|
-
var FOUNDER_DEMO_INITIATIVE_TITLE = "Founder Demo Initiative";
|
|
4750
|
-
var FOUNDER_DEMO_INITIATIVE_SUMMARY = "Starter initiative created by @useorgx/wizard to validate workspace routing, live views, and the default OrgX skill pack.";
|
|
4751
|
-
var FOUNDER_DEMO_DECISION_TITLE = "Approve founder demo workspace";
|
|
4752
|
-
var FOUNDER_DEMO_DECISION_SUMMARY = "Initial decision created by @useorgx/wizard so the founder preset leaves the workspace with a resolved approval trail.";
|
|
4753
|
-
var FOUNDER_DEMO_DECISION_RESOLUTION = "Approved automatically by @useorgx/wizard after the founder preset finished creating the live demo workspace.";
|
|
4754
|
-
var FOUNDER_DEMO_ARTIFACT_NAME = "Founder Demo Live View";
|
|
4755
|
-
var FOUNDER_DEMO_ARTIFACT_TYPE = "document";
|
|
4756
|
-
var FOUNDER_DEMO_ARTIFACT_DESCRIPTION = "Live founder demo generated by @useorgx/wizard after workspace bootstrap completed.";
|
|
4757
|
-
var ONBOARDING_TASK_TITLE = "Complete OrgX onboarding";
|
|
4758
|
-
var ONBOARDING_TASK_SUMMARY = "Starter onboarding task created by @useorgx/wizard so the first workspace has a clear follow-up after setup.";
|
|
4759
|
-
var ONBOARDING_WORKSTREAM_TITLE = "OrgX onboarding";
|
|
4760
|
-
var ONBOARDING_WORKSTREAM_SUMMARY = "Starter onboarding workstream created by @useorgx/wizard so the first workspace has a home for setup follow-up tasks.";
|
|
4761
|
-
var FIRST_VALUE_INITIATIVE_TITLE = "Make OrgX useful on this machine";
|
|
4762
|
-
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.";
|
|
4763
|
-
function parseResponseBody3(text2) {
|
|
4764
|
-
if (!text2) {
|
|
4765
|
-
return null;
|
|
4766
|
-
}
|
|
4767
|
-
try {
|
|
4768
|
-
return JSON.parse(text2);
|
|
4769
|
-
} catch {
|
|
4770
|
-
return text2;
|
|
4771
|
-
}
|
|
4772
|
-
}
|
|
4773
|
-
function formatHttpError2(status, body) {
|
|
4774
|
-
if (typeof body === "string" && body.trim().length > 0) {
|
|
4775
|
-
return `HTTP ${status}: ${body}`;
|
|
4776
|
-
}
|
|
4777
|
-
if (isRecord(body) && typeof body.error === "string" && body.error.trim().length > 0) {
|
|
4778
|
-
return `HTTP ${status}: ${body.error}`;
|
|
4779
|
-
}
|
|
4780
|
-
return `HTTP ${status}`;
|
|
4781
|
-
}
|
|
4782
|
-
function extractEntity(payload) {
|
|
4783
|
-
const entity = isRecord(payload) && isRecord(payload.data) ? payload.data : payload;
|
|
4784
|
-
if (!isRecord(entity)) {
|
|
4785
|
-
throw new Error("OrgX returned an unexpected entity payload.");
|
|
4786
|
-
}
|
|
4787
|
-
return entity;
|
|
4788
|
-
}
|
|
4789
|
-
function parseInitiative(payload) {
|
|
4790
|
-
const entity = extractEntity(payload);
|
|
4791
|
-
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
4792
|
-
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
4793
|
-
if (!id || !title) {
|
|
4794
|
-
throw new Error("OrgX returned an incomplete initiative payload.");
|
|
4795
|
-
}
|
|
4796
|
-
return {
|
|
4797
|
-
id,
|
|
4798
|
-
title,
|
|
4799
|
-
...typeof entity.summary === "string" && entity.summary.trim().length > 0 ? { summary: entity.summary.trim() } : {}
|
|
4800
|
-
};
|
|
4801
|
-
}
|
|
4802
|
-
function parseDecision(payload) {
|
|
4803
|
-
const entity = extractEntity(payload);
|
|
4804
|
-
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
4805
|
-
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
4806
|
-
if (!id || !title) {
|
|
4807
|
-
throw new Error("OrgX returned an incomplete decision payload.");
|
|
4808
|
-
}
|
|
4809
|
-
return {
|
|
4810
|
-
id,
|
|
4811
|
-
title,
|
|
4812
|
-
...typeof entity.status === "string" && entity.status.trim().length > 0 ? { status: entity.status.trim() } : {},
|
|
4813
|
-
...typeof entity.summary === "string" && entity.summary.trim().length > 0 ? { summary: entity.summary.trim() } : {}
|
|
4814
|
-
};
|
|
4815
|
-
}
|
|
4816
|
-
function parseArtifact(payload) {
|
|
4817
|
-
const entity = extractEntity(payload);
|
|
4818
|
-
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
4819
|
-
const name = typeof entity.name === "string" ? entity.name.trim() : typeof entity.title === "string" ? entity.title.trim() : "";
|
|
4820
|
-
const type = typeof entity.artifact_type === "string" ? entity.artifact_type.trim() : typeof entity.type === "string" ? entity.type.trim() : "";
|
|
4821
|
-
const url = typeof entity.external_url === "string" ? entity.external_url.trim() : typeof entity.url === "string" ? entity.url.trim() : "";
|
|
4822
|
-
if (!id || !name) {
|
|
4823
|
-
throw new Error("OrgX returned an incomplete artifact payload.");
|
|
4824
|
-
}
|
|
4825
|
-
return {
|
|
4826
|
-
id,
|
|
4827
|
-
name,
|
|
4828
|
-
...type ? { type } : {},
|
|
4829
|
-
...url ? { url } : {}
|
|
4830
|
-
};
|
|
4831
|
-
}
|
|
4832
|
-
function parseTask(payload) {
|
|
4833
|
-
const entity = extractEntity(payload);
|
|
4834
|
-
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
4835
|
-
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
4836
|
-
if (!id || !title) {
|
|
4837
|
-
throw new Error("OrgX returned an incomplete task payload.");
|
|
4838
|
-
}
|
|
4839
|
-
return {
|
|
4840
|
-
id,
|
|
4841
|
-
title,
|
|
4842
|
-
...typeof entity.status === "string" && entity.status.trim().length > 0 ? { status: entity.status.trim() } : {},
|
|
4843
|
-
...typeof entity.summary === "string" && entity.summary.trim().length > 0 ? { summary: entity.summary.trim() } : {}
|
|
4844
|
-
};
|
|
4845
|
-
}
|
|
4846
|
-
function parseWorkstream(payload) {
|
|
4847
|
-
const entity = extractEntity(payload);
|
|
4848
|
-
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
4849
|
-
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
4850
|
-
if (!id || !title) {
|
|
4851
|
-
throw new Error("OrgX returned an incomplete workstream payload.");
|
|
4852
|
-
}
|
|
4853
|
-
return { id, title };
|
|
4854
|
-
}
|
|
4855
|
-
function toDemoInitiativeRecord(artifact, decision, initiative, liveUrl, workspace) {
|
|
4856
|
-
return {
|
|
4857
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4858
|
-
artifactId: artifact.id,
|
|
4859
|
-
artifactName: artifact.name,
|
|
4860
|
-
...artifact.type ? { artifactType: artifact.type } : {},
|
|
4861
|
-
...artifact.url ? { artifactUrl: artifact.url } : {},
|
|
4862
|
-
decisionId: decision.id,
|
|
4863
|
-
...decision.status ? { decisionStatus: decision.status } : {},
|
|
4864
|
-
decisionTitle: decision.title,
|
|
4865
|
-
id: initiative.id,
|
|
4866
|
-
liveUrl,
|
|
4867
|
-
title: initiative.title,
|
|
4868
|
-
workspaceId: workspace.id,
|
|
4869
|
-
workspaceName: workspace.name
|
|
4870
|
-
};
|
|
4871
|
-
}
|
|
4872
|
-
function toOnboardingTaskRecord(task, workspace, options = {}) {
|
|
4873
|
-
return {
|
|
4874
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4875
|
-
id: task.id,
|
|
4876
|
-
...options.initiativeId ? { initiativeId: options.initiativeId } : {},
|
|
4877
|
-
...task.status ? { status: task.status } : {},
|
|
4878
|
-
title: task.title,
|
|
4879
|
-
...options.workstreamId ? { workstreamId: options.workstreamId } : {},
|
|
4880
|
-
workspaceId: workspace.id,
|
|
4881
|
-
workspaceName: workspace.name
|
|
4882
|
-
};
|
|
4883
|
-
}
|
|
4884
|
-
function toFirstValueInitiativeRecord(initiative, liveUrl, workspace) {
|
|
4885
|
-
return {
|
|
4886
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4887
|
-
id: initiative.id,
|
|
4888
|
-
liveUrl,
|
|
4889
|
-
...initiative.summary ? { summary: initiative.summary } : {},
|
|
4890
|
-
title: initiative.title,
|
|
4891
|
-
workspaceId: workspace.id,
|
|
4892
|
-
workspaceName: workspace.name
|
|
4893
|
-
};
|
|
4894
|
-
}
|
|
4895
|
-
async function requireOrgxAuth2(options = {}) {
|
|
4896
|
-
const auth = await resolveOrgxAuth(options);
|
|
4897
|
-
if (!auth) {
|
|
4898
|
-
throw new Error(
|
|
4899
|
-
"No OrgX API key configured. Run `wizard auth login` or `wizard auth set-key <oxk_...>` first."
|
|
4900
|
-
);
|
|
4901
|
-
}
|
|
4902
|
-
return auth;
|
|
4903
|
-
}
|
|
4904
|
-
async function createEntity(type, body, parse2, options = {}) {
|
|
4905
|
-
const auth = await requireOrgxAuth2(options);
|
|
4906
|
-
const response = await fetch(buildOrgxApiUrl("/entities", auth.baseUrl), {
|
|
4907
|
-
method: "POST",
|
|
4908
|
-
headers: {
|
|
4909
|
-
Authorization: `Bearer ${auth.apiKey}`,
|
|
4910
|
-
"Content-Type": "application/json"
|
|
4911
|
-
},
|
|
4912
|
-
body: JSON.stringify({
|
|
4913
|
-
type,
|
|
4914
|
-
...body
|
|
4915
|
-
}),
|
|
4916
|
-
signal: AbortSignal.timeout(7e3)
|
|
4917
|
-
});
|
|
4918
|
-
const responseBody = parseResponseBody3(await response.text());
|
|
4919
|
-
if (!response.ok) {
|
|
4920
|
-
throw new Error(`Failed to create ${type}. ${formatHttpError2(response.status, responseBody)}`);
|
|
4921
|
-
}
|
|
4922
|
-
return parse2(responseBody);
|
|
4923
|
-
}
|
|
4924
|
-
async function updateEntity(type, id, body, parse2, options = {}) {
|
|
4925
|
-
const auth = await requireOrgxAuth2(options);
|
|
4926
|
-
const response = await fetch(buildOrgxApiUrl("/entities", auth.baseUrl), {
|
|
4927
|
-
method: "PATCH",
|
|
4928
|
-
headers: {
|
|
4929
|
-
Authorization: `Bearer ${auth.apiKey}`,
|
|
4930
|
-
"Content-Type": "application/json"
|
|
4931
|
-
},
|
|
4932
|
-
body: JSON.stringify({
|
|
4933
|
-
type,
|
|
4934
|
-
id,
|
|
4935
|
-
...body
|
|
4936
|
-
}),
|
|
4937
|
-
signal: AbortSignal.timeout(7e3)
|
|
4938
|
-
});
|
|
4939
|
-
const responseBody = parseResponseBody3(await response.text());
|
|
4940
|
-
if (!response.ok) {
|
|
4941
|
-
throw new Error(`Failed to update ${type}. ${formatHttpError2(response.status, responseBody)}`);
|
|
4942
|
-
}
|
|
4943
|
-
return parse2(responseBody);
|
|
4944
|
-
}
|
|
4945
|
-
function buildLiveUrl(baseUrl, initiativeId) {
|
|
4946
|
-
const parsed = new URL(normalizeOrgxBaseUrl(baseUrl));
|
|
4947
|
-
parsed.pathname = `/live/${initiativeId}`;
|
|
4948
|
-
parsed.search = "";
|
|
4949
|
-
parsed.hash = "";
|
|
4950
|
-
return parsed.toString();
|
|
4951
|
-
}
|
|
4952
|
-
async function createFounderDemoDecision(initiative, workspaceId, options = {}) {
|
|
4953
|
-
return createEntity(
|
|
4954
|
-
"decision",
|
|
4955
|
-
{
|
|
4956
|
-
initiative_id: initiative.id,
|
|
4957
|
-
summary: FOUNDER_DEMO_DECISION_SUMMARY,
|
|
4958
|
-
title: FOUNDER_DEMO_DECISION_TITLE,
|
|
4959
|
-
workspace_id: workspaceId
|
|
4960
|
-
},
|
|
4961
|
-
parseDecision,
|
|
4962
|
-
options
|
|
4963
|
-
);
|
|
4964
|
-
}
|
|
4965
|
-
async function approveFounderDemoDecision(decisionId, options = {}) {
|
|
4966
|
-
return updateEntity(
|
|
4967
|
-
"decision",
|
|
4968
|
-
decisionId,
|
|
4969
|
-
{
|
|
4970
|
-
resolution_summary: FOUNDER_DEMO_DECISION_RESOLUTION,
|
|
4971
|
-
status: "approved"
|
|
4972
|
-
},
|
|
4973
|
-
parseDecision,
|
|
4974
|
-
options
|
|
4975
|
-
);
|
|
4976
|
-
}
|
|
4977
|
-
async function createFounderDemoArtifact(initiative, liveUrl, workspaceId, options = {}) {
|
|
4978
|
-
return createEntity(
|
|
4979
|
-
"artifact",
|
|
4980
|
-
{
|
|
4981
|
-
artifact_type: FOUNDER_DEMO_ARTIFACT_TYPE,
|
|
4982
|
-
description: FOUNDER_DEMO_ARTIFACT_DESCRIPTION,
|
|
4983
|
-
entity_id: initiative.id,
|
|
4984
|
-
entity_type: "initiative",
|
|
4985
|
-
external_url: liveUrl,
|
|
4986
|
-
initiative_id: initiative.id,
|
|
4987
|
-
name: FOUNDER_DEMO_ARTIFACT_NAME,
|
|
4988
|
-
workspace_id: workspaceId
|
|
4989
|
-
},
|
|
4990
|
-
parseArtifact,
|
|
4991
|
-
options
|
|
4992
|
-
);
|
|
4993
|
-
}
|
|
4994
|
-
async function createInitiative(input, options = {}) {
|
|
4995
|
-
const title = input.title.trim();
|
|
4996
|
-
if (!title) {
|
|
4997
|
-
throw new Error("Initiative title is required.");
|
|
4998
|
-
}
|
|
4999
|
-
return createEntity(
|
|
5000
|
-
"initiative",
|
|
5001
|
-
{
|
|
5002
|
-
title,
|
|
5003
|
-
status: "active",
|
|
5004
|
-
...input.summary?.trim() ? { summary: input.summary.trim() } : {},
|
|
5005
|
-
...input.workspaceId?.trim() ? { workspace_id: input.workspaceId.trim() } : {}
|
|
5006
|
-
},
|
|
5007
|
-
parseInitiative,
|
|
5008
|
-
options
|
|
5009
|
-
);
|
|
5010
|
-
}
|
|
5011
|
-
async function ensureFounderDemoInitiative(workspace, options = {}) {
|
|
5012
|
-
const existingRecord = readWizardState(options.statePath)?.demoInitiative;
|
|
5013
|
-
const matchingRecord = existingRecord?.workspaceId === workspace.id ? existingRecord : void 0;
|
|
5014
|
-
const auth = await requireOrgxAuth2(options);
|
|
5015
|
-
const initiative = matchingRecord ? {
|
|
5016
|
-
id: matchingRecord.id,
|
|
5017
|
-
title: matchingRecord.title
|
|
5018
|
-
} : await createInitiative(
|
|
5019
|
-
{
|
|
5020
|
-
title: FOUNDER_DEMO_INITIATIVE_TITLE,
|
|
5021
|
-
summary: FOUNDER_DEMO_INITIATIVE_SUMMARY,
|
|
5022
|
-
workspaceId: workspace.id
|
|
5023
|
-
},
|
|
5024
|
-
options
|
|
5025
|
-
);
|
|
5026
|
-
const liveUrl = matchingRecord?.liveUrl || buildLiveUrl(auth.baseUrl, initiative.id);
|
|
5027
|
-
const decision = matchingRecord?.decisionId ? matchingRecord.decisionStatus === "approved" && matchingRecord.decisionTitle ? {
|
|
5028
|
-
id: matchingRecord.decisionId,
|
|
5029
|
-
status: matchingRecord.decisionStatus,
|
|
5030
|
-
title: matchingRecord.decisionTitle
|
|
5031
|
-
} : await approveFounderDemoDecision(matchingRecord.decisionId, options) : await approveFounderDemoDecision(
|
|
5032
|
-
(await createFounderDemoDecision(initiative, workspace.id, options)).id,
|
|
5033
|
-
options
|
|
5034
|
-
);
|
|
5035
|
-
const artifact = matchingRecord?.artifactId && matchingRecord.artifactName ? {
|
|
5036
|
-
id: matchingRecord.artifactId,
|
|
5037
|
-
name: matchingRecord.artifactName,
|
|
5038
|
-
...matchingRecord.artifactType ? { type: matchingRecord.artifactType } : {},
|
|
5039
|
-
...matchingRecord.artifactUrl ? { url: matchingRecord.artifactUrl } : {}
|
|
5040
|
-
} : await createFounderDemoArtifact(initiative, liveUrl, workspace.id, options);
|
|
5041
|
-
const record = toDemoInitiativeRecord(artifact, decision, initiative, liveUrl, workspace);
|
|
5042
|
-
updateWizardState(
|
|
5043
|
-
(current) => ({
|
|
5044
|
-
...current,
|
|
5045
|
-
demoInitiative: record
|
|
5046
|
-
}),
|
|
5047
|
-
options.statePath
|
|
5048
|
-
);
|
|
5049
|
-
return {
|
|
5050
|
-
artifact,
|
|
5051
|
-
created: !matchingRecord,
|
|
5052
|
-
decision,
|
|
5053
|
-
initiative,
|
|
5054
|
-
liveUrl
|
|
5055
|
-
};
|
|
5056
|
-
}
|
|
5057
|
-
async function ensureFirstValueInitiative(workspace, options = {}) {
|
|
5058
|
-
const existingRecord = readWizardState(options.statePath)?.firstValueInitiative;
|
|
5059
|
-
const matchingRecord = existingRecord?.workspaceId === workspace.id ? existingRecord : void 0;
|
|
5060
|
-
const auth = await requireOrgxAuth2(options);
|
|
5061
|
-
if (matchingRecord) {
|
|
5062
|
-
return {
|
|
5063
|
-
created: false,
|
|
5064
|
-
initiative: {
|
|
5065
|
-
id: matchingRecord.id,
|
|
5066
|
-
title: matchingRecord.title,
|
|
5067
|
-
...matchingRecord.summary ? { summary: matchingRecord.summary } : {}
|
|
5068
|
-
},
|
|
5069
|
-
liveUrl: matchingRecord.liveUrl || buildLiveUrl(auth.baseUrl, matchingRecord.id)
|
|
5070
|
-
};
|
|
5071
|
-
}
|
|
5072
|
-
const initiative = await createInitiative(
|
|
5073
|
-
{
|
|
5074
|
-
title: options.title?.trim() || FIRST_VALUE_INITIATIVE_TITLE,
|
|
5075
|
-
summary: options.summary?.trim() || FIRST_VALUE_INITIATIVE_SUMMARY,
|
|
5076
|
-
workspaceId: workspace.id
|
|
5077
|
-
},
|
|
5078
|
-
options
|
|
5079
|
-
);
|
|
5080
|
-
const liveUrl = buildLiveUrl(auth.baseUrl, initiative.id);
|
|
5081
|
-
updateWizardState(
|
|
5082
|
-
(current) => ({
|
|
5083
|
-
...current,
|
|
5084
|
-
firstValueInitiative: toFirstValueInitiativeRecord(initiative, liveUrl, workspace)
|
|
5085
|
-
}),
|
|
5086
|
-
options.statePath
|
|
5087
|
-
);
|
|
5088
|
-
return {
|
|
5089
|
-
created: true,
|
|
5090
|
-
initiative,
|
|
5091
|
-
liveUrl
|
|
5092
|
-
};
|
|
5093
|
-
}
|
|
5094
|
-
async function ensureOnboardingTask(workspace, options = {}) {
|
|
5095
|
-
const existingRecord = readWizardState(options.statePath)?.onboardingTask;
|
|
5096
|
-
if (existingRecord?.workspaceId === workspace.id) {
|
|
5097
|
-
return {
|
|
5098
|
-
id: existingRecord.id,
|
|
5099
|
-
title: existingRecord.title,
|
|
5100
|
-
...existingRecord.status ? { status: existingRecord.status } : {}
|
|
5101
|
-
};
|
|
5102
|
-
}
|
|
5103
|
-
const initiativeId = options.initiativeId?.trim();
|
|
5104
|
-
if (!initiativeId) {
|
|
5105
|
-
throw new Error(
|
|
5106
|
-
"Starter onboarding task requires an initiative context. Re-run setup with the founder preset or create an initiative before requesting onboarding tasks."
|
|
5107
|
-
);
|
|
5108
|
-
}
|
|
5109
|
-
const workstream = await createEntity(
|
|
5110
|
-
"workstream",
|
|
5111
|
-
{
|
|
5112
|
-
initiative_id: initiativeId,
|
|
5113
|
-
status: "active",
|
|
5114
|
-
summary: ONBOARDING_WORKSTREAM_SUMMARY,
|
|
5115
|
-
title: ONBOARDING_WORKSTREAM_TITLE,
|
|
5116
|
-
workspace_id: workspace.id
|
|
5117
|
-
},
|
|
5118
|
-
parseWorkstream,
|
|
5119
|
-
options
|
|
5120
|
-
);
|
|
5121
|
-
const task = await createEntity(
|
|
5122
|
-
"task",
|
|
5123
|
-
{
|
|
5124
|
-
initiative_id: initiativeId,
|
|
5125
|
-
status: "todo",
|
|
5126
|
-
summary: ONBOARDING_TASK_SUMMARY,
|
|
5127
|
-
title: ONBOARDING_TASK_TITLE,
|
|
5128
|
-
workstream_id: workstream.id,
|
|
5129
|
-
workspace_id: workspace.id
|
|
5130
|
-
},
|
|
5131
|
-
parseTask,
|
|
5132
|
-
options
|
|
5133
|
-
);
|
|
5134
|
-
updateWizardState(
|
|
5135
|
-
(current) => ({
|
|
5136
|
-
...current,
|
|
5137
|
-
onboardingTask: toOnboardingTaskRecord(task, workspace, {
|
|
5138
|
-
initiativeId,
|
|
5139
|
-
workstreamId: workstream.id
|
|
5140
|
-
})
|
|
5141
|
-
}),
|
|
5142
|
-
options.statePath
|
|
5143
|
-
);
|
|
5144
|
-
return task;
|
|
5145
|
-
}
|
|
5146
|
-
|
|
5147
4744
|
// src/lib/setup-workspace.ts
|
|
5148
4745
|
var CREATE_WORKSPACE_VALUE = "__create_workspace__";
|
|
5149
4746
|
var SKIP_WORKSPACE_VALUE = "__skip_workspace__";
|
|
@@ -5317,79 +4914,309 @@ async function runWorkspaceSetup(client, prompts, options) {
|
|
|
5317
4914
|
if (typeof selected !== "string") {
|
|
5318
4915
|
return cancelResult(prompts);
|
|
5319
4916
|
}
|
|
5320
|
-
if (selected === SKIP_WORKSPACE_VALUE) {
|
|
5321
|
-
return {
|
|
5322
|
-
message: "Workspace bootstrap skipped.",
|
|
5323
|
-
status: "skipped",
|
|
5324
|
-
...currentWorkspace ? { workspace: currentWorkspace } : {}
|
|
5325
|
-
};
|
|
4917
|
+
if (selected === SKIP_WORKSPACE_VALUE) {
|
|
4918
|
+
return {
|
|
4919
|
+
message: "Workspace bootstrap skipped.",
|
|
4920
|
+
status: "skipped",
|
|
4921
|
+
...currentWorkspace ? { workspace: currentWorkspace } : {}
|
|
4922
|
+
};
|
|
4923
|
+
}
|
|
4924
|
+
if (selected === CREATE_WORKSPACE_VALUE) {
|
|
4925
|
+
return createAndSelectWorkspace(client, prompts);
|
|
4926
|
+
}
|
|
4927
|
+
const chosenWorkspace = workspaces.find((workspace) => workspace.id === selected);
|
|
4928
|
+
if (!chosenWorkspace) {
|
|
4929
|
+
throw new Error(`Selected workspace ${selected} is no longer available.`);
|
|
4930
|
+
}
|
|
4931
|
+
if (chosenWorkspace.isDefault) {
|
|
4932
|
+
return {
|
|
4933
|
+
defaultChanged: false,
|
|
4934
|
+
message: `"${chosenWorkspace.name}" is already the default OrgX workspace.`,
|
|
4935
|
+
status: "unchanged",
|
|
4936
|
+
workspace: chosenWorkspace
|
|
4937
|
+
};
|
|
4938
|
+
}
|
|
4939
|
+
const promoted = await client.setDefaultWorkspace({ id: chosenWorkspace.id });
|
|
4940
|
+
return {
|
|
4941
|
+
defaultChanged: promoted.changed,
|
|
4942
|
+
message: `Set "${promoted.workspace.name}" as the default OrgX workspace.`,
|
|
4943
|
+
status: promoted.changed ? "updated" : "unchanged",
|
|
4944
|
+
workspace: promoted.workspace
|
|
4945
|
+
};
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4948
|
+
// src/lib/founder-preset.ts
|
|
4949
|
+
async function runFounderPreset(prompts, options) {
|
|
4950
|
+
const surfaceResults = await setupDetectedSurfaces();
|
|
4951
|
+
const pluginTargets = options.pluginTargets ?? (await listOrgxPluginStatuses()).filter((status) => status.installed).map((status) => status.target);
|
|
4952
|
+
const skillReport = await installOrgxSkills({
|
|
4953
|
+
pluginTargets,
|
|
4954
|
+
skillNames: [...DEFAULT_ORGX_SKILL_PACKS]
|
|
4955
|
+
});
|
|
4956
|
+
let workspaceSetup;
|
|
4957
|
+
let workspace = await getCurrentWorkspace().catch(() => null);
|
|
4958
|
+
if (workspace || options.interactive) {
|
|
4959
|
+
workspaceSetup = await runWorkspaceSetup(
|
|
4960
|
+
{
|
|
4961
|
+
createWorkspace,
|
|
4962
|
+
getCurrentWorkspace,
|
|
4963
|
+
listWorkspaces,
|
|
4964
|
+
setDefaultWorkspace
|
|
4965
|
+
},
|
|
4966
|
+
prompts,
|
|
4967
|
+
options
|
|
4968
|
+
);
|
|
4969
|
+
if (workspaceSetup.status === "cancelled") {
|
|
4970
|
+
return workspaceSetup;
|
|
4971
|
+
}
|
|
4972
|
+
workspace = workspaceSetup.workspace ?? workspace ?? await getCurrentWorkspace().catch(() => null);
|
|
4973
|
+
}
|
|
4974
|
+
const continuity = persistContinuityDefaults({
|
|
4975
|
+
statuses: listSurfaceStatuses(),
|
|
4976
|
+
workspace
|
|
4977
|
+
});
|
|
4978
|
+
return {
|
|
4979
|
+
continuity,
|
|
4980
|
+
skillReport,
|
|
4981
|
+
surfaceResults,
|
|
4982
|
+
workspace,
|
|
4983
|
+
...workspaceSetup ? { workspaceSetup } : {}
|
|
4984
|
+
};
|
|
4985
|
+
}
|
|
4986
|
+
|
|
4987
|
+
// src/lib/initiatives.ts
|
|
4988
|
+
var ONBOARDING_TASK_TITLE = "Complete OrgX onboarding";
|
|
4989
|
+
var ONBOARDING_TASK_SUMMARY = "Starter onboarding task created by @useorgx/wizard so the first workspace has a clear follow-up after setup.";
|
|
4990
|
+
var ONBOARDING_WORKSTREAM_TITLE = "OrgX onboarding";
|
|
4991
|
+
var ONBOARDING_WORKSTREAM_SUMMARY = "Starter onboarding workstream created by @useorgx/wizard so the first workspace has a home for setup follow-up tasks.";
|
|
4992
|
+
var FIRST_VALUE_INITIATIVE_TITLE = "Make OrgX useful on this machine";
|
|
4993
|
+
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.";
|
|
4994
|
+
function parseResponseBody3(text2) {
|
|
4995
|
+
if (!text2) {
|
|
4996
|
+
return null;
|
|
4997
|
+
}
|
|
4998
|
+
try {
|
|
4999
|
+
return JSON.parse(text2);
|
|
5000
|
+
} catch {
|
|
5001
|
+
return text2;
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
function formatHttpError2(status, body) {
|
|
5005
|
+
if (typeof body === "string" && body.trim().length > 0) {
|
|
5006
|
+
return `HTTP ${status}: ${body}`;
|
|
5007
|
+
}
|
|
5008
|
+
if (isRecord(body) && typeof body.error === "string" && body.error.trim().length > 0) {
|
|
5009
|
+
return `HTTP ${status}: ${body.error}`;
|
|
5010
|
+
}
|
|
5011
|
+
return `HTTP ${status}`;
|
|
5012
|
+
}
|
|
5013
|
+
function extractEntity(payload) {
|
|
5014
|
+
const entity = isRecord(payload) && isRecord(payload.data) ? payload.data : payload;
|
|
5015
|
+
if (!isRecord(entity)) {
|
|
5016
|
+
throw new Error("OrgX returned an unexpected entity payload.");
|
|
5017
|
+
}
|
|
5018
|
+
return entity;
|
|
5019
|
+
}
|
|
5020
|
+
function parseInitiative(payload) {
|
|
5021
|
+
const entity = extractEntity(payload);
|
|
5022
|
+
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
5023
|
+
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
5024
|
+
if (!id || !title) {
|
|
5025
|
+
throw new Error("OrgX returned an incomplete initiative payload.");
|
|
5026
|
+
}
|
|
5027
|
+
return {
|
|
5028
|
+
id,
|
|
5029
|
+
title,
|
|
5030
|
+
...typeof entity.summary === "string" && entity.summary.trim().length > 0 ? { summary: entity.summary.trim() } : {}
|
|
5031
|
+
};
|
|
5032
|
+
}
|
|
5033
|
+
function parseTask(payload) {
|
|
5034
|
+
const entity = extractEntity(payload);
|
|
5035
|
+
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
5036
|
+
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
5037
|
+
if (!id || !title) {
|
|
5038
|
+
throw new Error("OrgX returned an incomplete task payload.");
|
|
5039
|
+
}
|
|
5040
|
+
return {
|
|
5041
|
+
id,
|
|
5042
|
+
title,
|
|
5043
|
+
...typeof entity.status === "string" && entity.status.trim().length > 0 ? { status: entity.status.trim() } : {},
|
|
5044
|
+
...typeof entity.summary === "string" && entity.summary.trim().length > 0 ? { summary: entity.summary.trim() } : {}
|
|
5045
|
+
};
|
|
5046
|
+
}
|
|
5047
|
+
function parseWorkstream(payload) {
|
|
5048
|
+
const entity = extractEntity(payload);
|
|
5049
|
+
const id = typeof entity.id === "string" ? entity.id.trim() : "";
|
|
5050
|
+
const title = typeof entity.title === "string" ? entity.title.trim() : typeof entity.name === "string" ? entity.name.trim() : "";
|
|
5051
|
+
if (!id || !title) {
|
|
5052
|
+
throw new Error("OrgX returned an incomplete workstream payload.");
|
|
5053
|
+
}
|
|
5054
|
+
return { id, title };
|
|
5055
|
+
}
|
|
5056
|
+
function toOnboardingTaskRecord(task, workspace, options = {}) {
|
|
5057
|
+
return {
|
|
5058
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5059
|
+
id: task.id,
|
|
5060
|
+
...options.initiativeId ? { initiativeId: options.initiativeId } : {},
|
|
5061
|
+
...task.status ? { status: task.status } : {},
|
|
5062
|
+
title: task.title,
|
|
5063
|
+
...options.workstreamId ? { workstreamId: options.workstreamId } : {},
|
|
5064
|
+
workspaceId: workspace.id,
|
|
5065
|
+
workspaceName: workspace.name
|
|
5066
|
+
};
|
|
5067
|
+
}
|
|
5068
|
+
function toFirstValueInitiativeRecord(initiative, liveUrl, workspace) {
|
|
5069
|
+
return {
|
|
5070
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5071
|
+
id: initiative.id,
|
|
5072
|
+
liveUrl,
|
|
5073
|
+
...initiative.summary ? { summary: initiative.summary } : {},
|
|
5074
|
+
title: initiative.title,
|
|
5075
|
+
workspaceId: workspace.id,
|
|
5076
|
+
workspaceName: workspace.name
|
|
5077
|
+
};
|
|
5078
|
+
}
|
|
5079
|
+
async function requireOrgxAuth2(options = {}) {
|
|
5080
|
+
const auth = await resolveOrgxAuth(options);
|
|
5081
|
+
if (!auth) {
|
|
5082
|
+
throw new Error(
|
|
5083
|
+
"No OrgX API key configured. Run `wizard auth login` or `wizard auth set-key <oxk_...>` first."
|
|
5084
|
+
);
|
|
5326
5085
|
}
|
|
5327
|
-
|
|
5328
|
-
|
|
5086
|
+
return auth;
|
|
5087
|
+
}
|
|
5088
|
+
async function createEntity(type, body, parse2, options = {}) {
|
|
5089
|
+
const auth = await requireOrgxAuth2(options);
|
|
5090
|
+
const response = await fetch(buildOrgxApiUrl("/entities", auth.baseUrl), {
|
|
5091
|
+
method: "POST",
|
|
5092
|
+
headers: {
|
|
5093
|
+
Authorization: `Bearer ${auth.apiKey}`,
|
|
5094
|
+
"Content-Type": "application/json"
|
|
5095
|
+
},
|
|
5096
|
+
body: JSON.stringify({
|
|
5097
|
+
type,
|
|
5098
|
+
...body
|
|
5099
|
+
}),
|
|
5100
|
+
signal: AbortSignal.timeout(7e3)
|
|
5101
|
+
});
|
|
5102
|
+
const responseBody = parseResponseBody3(await response.text());
|
|
5103
|
+
if (!response.ok) {
|
|
5104
|
+
throw new Error(`Failed to create ${type}. ${formatHttpError2(response.status, responseBody)}`);
|
|
5329
5105
|
}
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5106
|
+
return parse2(responseBody);
|
|
5107
|
+
}
|
|
5108
|
+
function buildLiveUrl(baseUrl, initiativeId) {
|
|
5109
|
+
const parsed = new URL(normalizeOrgxBaseUrl(baseUrl));
|
|
5110
|
+
parsed.pathname = `/live/${initiativeId}`;
|
|
5111
|
+
parsed.search = "";
|
|
5112
|
+
parsed.hash = "";
|
|
5113
|
+
return parsed.toString();
|
|
5114
|
+
}
|
|
5115
|
+
async function createInitiative(input, options = {}) {
|
|
5116
|
+
const title = input.title.trim();
|
|
5117
|
+
if (!title) {
|
|
5118
|
+
throw new Error("Initiative title is required.");
|
|
5333
5119
|
}
|
|
5334
|
-
|
|
5120
|
+
return createEntity(
|
|
5121
|
+
"initiative",
|
|
5122
|
+
{
|
|
5123
|
+
title,
|
|
5124
|
+
status: "active",
|
|
5125
|
+
...input.summary?.trim() ? { summary: input.summary.trim() } : {},
|
|
5126
|
+
...input.workspaceId?.trim() ? { workspace_id: input.workspaceId.trim() } : {}
|
|
5127
|
+
},
|
|
5128
|
+
parseInitiative,
|
|
5129
|
+
options
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
async function ensureFirstValueInitiative(workspace, options = {}) {
|
|
5133
|
+
const existingRecord = readWizardState(options.statePath)?.firstValueInitiative;
|
|
5134
|
+
const matchingRecord = existingRecord?.workspaceId === workspace.id ? existingRecord : void 0;
|
|
5135
|
+
const auth = await requireOrgxAuth2(options);
|
|
5136
|
+
if (matchingRecord) {
|
|
5335
5137
|
return {
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5138
|
+
created: false,
|
|
5139
|
+
initiative: {
|
|
5140
|
+
id: matchingRecord.id,
|
|
5141
|
+
title: matchingRecord.title,
|
|
5142
|
+
...matchingRecord.summary ? { summary: matchingRecord.summary } : {}
|
|
5143
|
+
},
|
|
5144
|
+
liveUrl: matchingRecord.liveUrl || buildLiveUrl(auth.baseUrl, matchingRecord.id)
|
|
5340
5145
|
};
|
|
5341
5146
|
}
|
|
5342
|
-
const
|
|
5147
|
+
const initiative = await createInitiative(
|
|
5148
|
+
{
|
|
5149
|
+
title: options.title?.trim() || FIRST_VALUE_INITIATIVE_TITLE,
|
|
5150
|
+
summary: options.summary?.trim() || FIRST_VALUE_INITIATIVE_SUMMARY,
|
|
5151
|
+
workspaceId: workspace.id
|
|
5152
|
+
},
|
|
5153
|
+
options
|
|
5154
|
+
);
|
|
5155
|
+
const liveUrl = buildLiveUrl(auth.baseUrl, initiative.id);
|
|
5156
|
+
updateWizardState(
|
|
5157
|
+
(current) => ({
|
|
5158
|
+
...current,
|
|
5159
|
+
firstValueInitiative: toFirstValueInitiativeRecord(initiative, liveUrl, workspace)
|
|
5160
|
+
}),
|
|
5161
|
+
options.statePath
|
|
5162
|
+
);
|
|
5343
5163
|
return {
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
workspace: promoted.workspace
|
|
5164
|
+
created: true,
|
|
5165
|
+
initiative,
|
|
5166
|
+
liveUrl
|
|
5348
5167
|
};
|
|
5349
5168
|
}
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
});
|
|
5359
|
-
let workspaceSetup;
|
|
5360
|
-
let workspace = await getCurrentWorkspace().catch(() => null);
|
|
5361
|
-
if (workspace || options.interactive) {
|
|
5362
|
-
workspaceSetup = await runWorkspaceSetup(
|
|
5363
|
-
{
|
|
5364
|
-
createWorkspace,
|
|
5365
|
-
getCurrentWorkspace,
|
|
5366
|
-
listWorkspaces,
|
|
5367
|
-
setDefaultWorkspace
|
|
5368
|
-
},
|
|
5369
|
-
prompts,
|
|
5370
|
-
options
|
|
5371
|
-
);
|
|
5372
|
-
if (workspaceSetup.status === "cancelled") {
|
|
5373
|
-
return workspaceSetup;
|
|
5374
|
-
}
|
|
5375
|
-
workspace = workspaceSetup.workspace ?? workspace ?? await getCurrentWorkspace().catch(() => null);
|
|
5169
|
+
async function ensureOnboardingTask(workspace, options = {}) {
|
|
5170
|
+
const existingRecord = readWizardState(options.statePath)?.onboardingTask;
|
|
5171
|
+
if (existingRecord?.workspaceId === workspace.id) {
|
|
5172
|
+
return {
|
|
5173
|
+
id: existingRecord.id,
|
|
5174
|
+
title: existingRecord.title,
|
|
5175
|
+
...existingRecord.status ? { status: existingRecord.status } : {}
|
|
5176
|
+
};
|
|
5376
5177
|
}
|
|
5377
|
-
const
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
if (workspace) {
|
|
5383
|
-
demoInitiative = await ensureFounderDemoInitiative(workspace);
|
|
5178
|
+
const initiativeId = options.initiativeId?.trim();
|
|
5179
|
+
if (!initiativeId) {
|
|
5180
|
+
throw new Error(
|
|
5181
|
+
"Starter onboarding task requires an initiative context. Re-run setup with the founder preset or create an initiative before requesting onboarding tasks."
|
|
5182
|
+
);
|
|
5384
5183
|
}
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5184
|
+
const workstream = await createEntity(
|
|
5185
|
+
"workstream",
|
|
5186
|
+
{
|
|
5187
|
+
initiative_id: initiativeId,
|
|
5188
|
+
status: "active",
|
|
5189
|
+
summary: ONBOARDING_WORKSTREAM_SUMMARY,
|
|
5190
|
+
title: ONBOARDING_WORKSTREAM_TITLE,
|
|
5191
|
+
workspace_id: workspace.id
|
|
5192
|
+
},
|
|
5193
|
+
parseWorkstream,
|
|
5194
|
+
options
|
|
5195
|
+
);
|
|
5196
|
+
const task = await createEntity(
|
|
5197
|
+
"task",
|
|
5198
|
+
{
|
|
5199
|
+
initiative_id: initiativeId,
|
|
5200
|
+
status: "todo",
|
|
5201
|
+
summary: ONBOARDING_TASK_SUMMARY,
|
|
5202
|
+
title: ONBOARDING_TASK_TITLE,
|
|
5203
|
+
workstream_id: workstream.id,
|
|
5204
|
+
workspace_id: workspace.id
|
|
5205
|
+
},
|
|
5206
|
+
parseTask,
|
|
5207
|
+
options
|
|
5208
|
+
);
|
|
5209
|
+
updateWizardState(
|
|
5210
|
+
(current) => ({
|
|
5211
|
+
...current,
|
|
5212
|
+
onboardingTask: toOnboardingTaskRecord(task, workspace, {
|
|
5213
|
+
initiativeId,
|
|
5214
|
+
workstreamId: workstream.id
|
|
5215
|
+
})
|
|
5216
|
+
}),
|
|
5217
|
+
options.statePath
|
|
5218
|
+
);
|
|
5219
|
+
return task;
|
|
5393
5220
|
}
|
|
5394
5221
|
|
|
5395
5222
|
// src/lib/local-skill-discovery.ts
|
|
@@ -5607,6 +5434,9 @@ var HOSTED_MCP_OUTAGE_TITLE = "Hosted OrgX MCP is unreachable.";
|
|
|
5607
5434
|
function getSetupVerificationHeadline(summary) {
|
|
5608
5435
|
switch (summary.status) {
|
|
5609
5436
|
case "degraded":
|
|
5437
|
+
if (summary.transientTimeouts) {
|
|
5438
|
+
return "OrgX servers were slow to respond \u2014 setup applied, but the final health check timed out. Re-run `wizard doctor` in a moment to confirm.";
|
|
5439
|
+
}
|
|
5610
5440
|
return "Hosted OrgX MCP is down; local setup can still continue.";
|
|
5611
5441
|
case "error":
|
|
5612
5442
|
return "Issues detected";
|
|
@@ -5616,18 +5446,50 @@ function getSetupVerificationHeadline(summary) {
|
|
|
5616
5446
|
return "All systems ready.";
|
|
5617
5447
|
}
|
|
5618
5448
|
}
|
|
5619
|
-
function
|
|
5449
|
+
function isTimeoutErrorString(value) {
|
|
5450
|
+
if (!value) return false;
|
|
5451
|
+
return isTimeoutError(new Error(value));
|
|
5452
|
+
}
|
|
5453
|
+
function reportErrorsAreOnlyTimeouts(report) {
|
|
5454
|
+
if (!report) return false;
|
|
5455
|
+
const authTimedOut = !report.auth.ok && !report.auth.skipped && isTimeoutErrorString(report.auth.error);
|
|
5456
|
+
const workspaceTimedOut = !report.workspace.ok && !report.workspace.skipped && isTimeoutErrorString(report.workspace.error);
|
|
5457
|
+
const reachableServicesOk = (report.hostedMcp.skipped || report.hostedMcp.ok) && (report.openclaw.skipped || report.openclaw.ok);
|
|
5458
|
+
return reachableServicesOk && (authTimedOut || workspaceTimedOut);
|
|
5459
|
+
}
|
|
5460
|
+
function summarizeSetupVerification(assessment, report) {
|
|
5620
5461
|
const errors = assessment.issues.filter((issue) => issue.level === "error");
|
|
5621
5462
|
if (errors.length === 0) {
|
|
5622
5463
|
return {
|
|
5623
5464
|
hostedMcpDegraded: false,
|
|
5465
|
+
transientTimeouts: false,
|
|
5624
5466
|
status: assessment.issues.length > 0 ? "warning" : "ok"
|
|
5625
5467
|
};
|
|
5626
5468
|
}
|
|
5627
5469
|
const hostedMcpDegraded = errors.every((issue) => issue.title === HOSTED_MCP_OUTAGE_TITLE);
|
|
5470
|
+
if (hostedMcpDegraded) {
|
|
5471
|
+
return {
|
|
5472
|
+
hostedMcpDegraded: true,
|
|
5473
|
+
transientTimeouts: false,
|
|
5474
|
+
status: "degraded"
|
|
5475
|
+
};
|
|
5476
|
+
}
|
|
5477
|
+
const authOrWorkspaceTitles = /* @__PURE__ */ new Set([
|
|
5478
|
+
"OrgX user auth could not be verified.",
|
|
5479
|
+
"Current workspace lookup failed."
|
|
5480
|
+
]);
|
|
5481
|
+
const onlyAuthOrWorkspaceErrors = errors.every((issue) => authOrWorkspaceTitles.has(issue.title));
|
|
5482
|
+
if (onlyAuthOrWorkspaceErrors && reportErrorsAreOnlyTimeouts(report)) {
|
|
5483
|
+
return {
|
|
5484
|
+
hostedMcpDegraded: false,
|
|
5485
|
+
transientTimeouts: true,
|
|
5486
|
+
status: "degraded"
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5628
5489
|
return {
|
|
5629
|
-
hostedMcpDegraded,
|
|
5630
|
-
|
|
5490
|
+
hostedMcpDegraded: false,
|
|
5491
|
+
transientTimeouts: false,
|
|
5492
|
+
status: "error"
|
|
5631
5493
|
};
|
|
5632
5494
|
}
|
|
5633
5495
|
|
|
@@ -5669,16 +5531,6 @@ function buildAgentRosterTelemetryProperties(input, base = {}) {
|
|
|
5669
5531
|
base
|
|
5670
5532
|
);
|
|
5671
5533
|
}
|
|
5672
|
-
function buildFounderDemoTelemetryProperties(result, base = {}) {
|
|
5673
|
-
return withBaseProperties(
|
|
5674
|
-
{
|
|
5675
|
-
created: result.created,
|
|
5676
|
-
decision_status: result.decision.status ?? "unknown",
|
|
5677
|
-
has_artifact_url: Boolean(result.artifact.url)
|
|
5678
|
-
},
|
|
5679
|
-
base
|
|
5680
|
-
);
|
|
5681
|
-
}
|
|
5682
5534
|
function buildFirstValueInitiativeTelemetryProperties(result, base = {}) {
|
|
5683
5535
|
return withBaseProperties(
|
|
5684
5536
|
{
|
|
@@ -5701,6 +5553,7 @@ function buildDoctorTelemetryProperties(report, assessment, verification, base =
|
|
|
5701
5553
|
hosted_mcp_degraded: verification.hostedMcpDegraded,
|
|
5702
5554
|
hosted_mcp_ok: report.hostedMcp.ok,
|
|
5703
5555
|
hosted_mcp_tool_ok: report.hostedMcpTool.ok,
|
|
5556
|
+
transient_timeouts: verification.transientTimeouts,
|
|
5704
5557
|
issue_count: assessment.issues.length,
|
|
5705
5558
|
openclaw_available: !report.openclaw.skipped,
|
|
5706
5559
|
openclaw_ok: report.openclaw.ok,
|
|
@@ -14050,20 +13903,6 @@ function printFounderPresetResult(result) {
|
|
|
14050
13903
|
console.log("");
|
|
14051
13904
|
printWorkspaceSetupResult(result.workspaceSetup);
|
|
14052
13905
|
}
|
|
14053
|
-
if (result.demoInitiative) {
|
|
14054
|
-
console.log("");
|
|
14055
|
-
console.log(pc3.bold("demo initiative"));
|
|
14056
|
-
console.log(
|
|
14057
|
-
` ${result.demoInitiative.created ? pc3.green("created") : pc3.yellow("unchanged")} ${result.demoInitiative.initiative.title}`
|
|
14058
|
-
);
|
|
14059
|
-
console.log(` live: ${result.demoInitiative.liveUrl}`);
|
|
14060
|
-
console.log(
|
|
14061
|
-
` decision: ${result.demoInitiative.decision.title} ${pc3.dim(`(${result.demoInitiative.decision.status ?? "pending"})`)}`
|
|
14062
|
-
);
|
|
14063
|
-
console.log(
|
|
14064
|
-
` artifact: ${result.demoInitiative.artifact.name}${result.demoInitiative.artifact.url ? ` ${pc3.dim(result.demoInitiative.artifact.url)}` : ""}`
|
|
14065
|
-
);
|
|
14066
|
-
}
|
|
14067
13906
|
}
|
|
14068
13907
|
function normalizePromptResult(value) {
|
|
14069
13908
|
return value;
|
|
@@ -14488,10 +14327,9 @@ async function maybeConfigureOptionalWorkspaceAddOns(input) {
|
|
|
14488
14327
|
}
|
|
14489
14328
|
const existingState = readWizardState();
|
|
14490
14329
|
const providedInitiativeId = input.initiativeId?.trim();
|
|
14491
|
-
const storedDemoInitiative = existingState?.demoInitiative?.workspaceId === input.workspace.id ? existingState.demoInitiative : void 0;
|
|
14492
14330
|
const storedFirstValueInitiative = existingState?.firstValueInitiative?.workspaceId === input.workspace.id ? existingState.firstValueInitiative : void 0;
|
|
14493
|
-
let effectiveInitiativeId = providedInitiativeId ||
|
|
14494
|
-
let firstValueInitiative = providedInitiativeId
|
|
14331
|
+
let effectiveInitiativeId = providedInitiativeId || storedFirstValueInitiative?.id;
|
|
14332
|
+
let firstValueInitiative = providedInitiativeId ? null : firstValueRecordToResult(storedFirstValueInitiative);
|
|
14495
14333
|
const firstInitiativeSkipped = hasSetupPromptSkip(
|
|
14496
14334
|
input.workspace.id,
|
|
14497
14335
|
"first_initiative"
|
|
@@ -14845,7 +14683,7 @@ function printAuthStatus(status) {
|
|
|
14845
14683
|
}
|
|
14846
14684
|
}
|
|
14847
14685
|
function printDoctorReport(report, assessment) {
|
|
14848
|
-
const verification = summarizeSetupVerification(assessment);
|
|
14686
|
+
const verification = summarizeSetupVerification(assessment, report);
|
|
14849
14687
|
console.log(pc3.dim(" surfaces"));
|
|
14850
14688
|
printSurfaceTable(report.surfaces);
|
|
14851
14689
|
console.log("");
|
|
@@ -14893,6 +14731,9 @@ function printDoctorReport(report, assessment) {
|
|
|
14893
14731
|
} else {
|
|
14894
14732
|
console.log(` ${pc3.dim("\u2192")} ${pc3.dim(`OrgX is active across ${configuredCount} editor${configuredCount !== 1 ? "s" : ""}`)}`);
|
|
14895
14733
|
}
|
|
14734
|
+
} else if (verification.transientTimeouts) {
|
|
14735
|
+
console.log(` ${ICON.warn} ${pc3.yellow(getSetupVerificationHeadline(verification))}`);
|
|
14736
|
+
console.log(` ${pc3.dim("\u2192")} ${pc3.cyan(`${getCmd()} doctor`)} ${pc3.dim("re-runs the health checks")}`);
|
|
14896
14737
|
} else {
|
|
14897
14738
|
const headlineText = getSetupVerificationHeadline(verification);
|
|
14898
14739
|
const headline = verification.status === "error" ? `${ICON.err} ${pc3.red(headlineText)}` : `${ICON.warn} ${pc3.yellow(headlineText)}`;
|
|
@@ -14909,7 +14750,7 @@ function printDoctorReport(report, assessment) {
|
|
|
14909
14750
|
async function main() {
|
|
14910
14751
|
const program = new Command();
|
|
14911
14752
|
program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
|
|
14912
|
-
const pkgVersion = true ? "0.1.
|
|
14753
|
+
const pkgVersion = true ? "0.1.47" : void 0;
|
|
14913
14754
|
program.version(pkgVersion ?? "unknown", "-V, --version");
|
|
14914
14755
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
14915
14756
|
if (Boolean(actionCommand.optsWithGlobals().json)) return;
|
|
@@ -14988,22 +14829,12 @@ async function main() {
|
|
|
14988
14829
|
})
|
|
14989
14830
|
);
|
|
14990
14831
|
}
|
|
14991
|
-
if (presetResult.demoInitiative) {
|
|
14992
|
-
await safeTrackWizardTelemetry(
|
|
14993
|
-
"founder_demo_ready",
|
|
14994
|
-
buildFounderDemoTelemetryProperties(presetResult.demoInitiative, {
|
|
14995
|
-
command: "setup",
|
|
14996
|
-
preset: "founder"
|
|
14997
|
-
})
|
|
14998
|
-
);
|
|
14999
|
-
}
|
|
15000
14832
|
const addOnResult = await maybeConfigureOptionalWorkspaceAddOns({
|
|
15001
14833
|
...setupContext ? { context: setupContext } : {},
|
|
15002
14834
|
interactive,
|
|
15003
14835
|
profile: setupProfile,
|
|
15004
14836
|
telemetry: { command: "setup", preset: "founder" },
|
|
15005
|
-
workspace: presetResult.workspace
|
|
15006
|
-
...presetResult.demoInitiative ? { initiativeId: presetResult.demoInitiative.initiative.id } : {}
|
|
14837
|
+
workspace: presetResult.workspace
|
|
15007
14838
|
});
|
|
15008
14839
|
if (addOnResult === "cancelled") {
|
|
15009
14840
|
return;
|
|
@@ -15015,7 +14846,7 @@ async function main() {
|
|
|
15015
14846
|
console.log("");
|
|
15016
14847
|
const doctor2 = await runDoctor();
|
|
15017
14848
|
const assessment2 = assessDoctorReport(doctor2);
|
|
15018
|
-
const verification2 = summarizeSetupVerification(assessment2);
|
|
14849
|
+
const verification2 = summarizeSetupVerification(assessment2, doctor2);
|
|
15019
14850
|
await safeTrackWizardTelemetry(
|
|
15020
14851
|
"setup_verified",
|
|
15021
14852
|
buildDoctorTelemetryProperties(doctor2, assessment2, verification2, {
|
|
@@ -15042,6 +14873,7 @@ async function main() {
|
|
|
15042
14873
|
});
|
|
15043
14874
|
const wasAlreadyPaired = await resolveOrgxAuth() !== null;
|
|
15044
14875
|
let resolvedAuth = await resolveOrgxAuth();
|
|
14876
|
+
let cachedWorkspaceCheck;
|
|
15045
14877
|
if (!resolvedAuth) {
|
|
15046
14878
|
console.log("");
|
|
15047
14879
|
if (interactive) {
|
|
@@ -15125,6 +14957,20 @@ async function main() {
|
|
|
15125
14957
|
})
|
|
15126
14958
|
);
|
|
15127
14959
|
const resolvedWorkspace = workspaceSetup.workspace ?? await getCurrentWorkspace().catch(() => null);
|
|
14960
|
+
if (resolvedWorkspace && resolvedAuth) {
|
|
14961
|
+
cachedWorkspaceCheck = {
|
|
14962
|
+
configured: true,
|
|
14963
|
+
ok: true,
|
|
14964
|
+
skipped: false,
|
|
14965
|
+
source: resolvedAuth.source,
|
|
14966
|
+
baseUrl: resolvedAuth.baseUrl,
|
|
14967
|
+
workspace: resolvedWorkspace,
|
|
14968
|
+
details: [
|
|
14969
|
+
`workspace id: ${resolvedWorkspace.id}`,
|
|
14970
|
+
...resolvedWorkspace.isDefault ? ["workspace is marked as default"] : []
|
|
14971
|
+
]
|
|
14972
|
+
};
|
|
14973
|
+
}
|
|
15128
14974
|
if (resolvedWorkspace) {
|
|
15129
14975
|
persistContinuityDefaults({ workspace: resolvedWorkspace });
|
|
15130
14976
|
}
|
|
@@ -15179,9 +15025,11 @@ async function main() {
|
|
|
15179
15025
|
return;
|
|
15180
15026
|
}
|
|
15181
15027
|
}
|
|
15182
|
-
const doctor = await runDoctor(
|
|
15028
|
+
const doctor = await runDoctor(
|
|
15029
|
+
cachedWorkspaceCheck ? { cachedWorkspace: cachedWorkspaceCheck } : {}
|
|
15030
|
+
);
|
|
15183
15031
|
const assessment = assessDoctorReport(doctor);
|
|
15184
|
-
const verification = summarizeSetupVerification(assessment);
|
|
15032
|
+
const verification = summarizeSetupVerification(assessment, doctor);
|
|
15185
15033
|
await safeTrackWizardTelemetry(
|
|
15186
15034
|
"setup_verified",
|
|
15187
15035
|
buildDoctorTelemetryProperties(doctor, assessment, verification, {
|
|
@@ -15698,7 +15546,7 @@ async function main() {
|
|
|
15698
15546
|
const report = await runDoctor();
|
|
15699
15547
|
spinner.stop();
|
|
15700
15548
|
const assessment = assessDoctorReport(report);
|
|
15701
|
-
const verification = summarizeSetupVerification(assessment);
|
|
15549
|
+
const verification = summarizeSetupVerification(assessment, report);
|
|
15702
15550
|
await safeTrackWizardTelemetry(
|
|
15703
15551
|
"doctor_ran",
|
|
15704
15552
|
buildDoctorTelemetryProperties(report, assessment, verification, {
|