@useorgx/wizard 0.1.22 → 0.1.24
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 +485 -94
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import * as clack from "@clack/prompts";
|
|
5
5
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
6
|
-
import { readFileSync as
|
|
6
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
7
7
|
import { hostname } from "os";
|
|
8
8
|
import { resolve } from "path";
|
|
9
9
|
import { Command } from "commander";
|
|
@@ -81,6 +81,8 @@ var CURSOR_DIR = join(HOME, ".cursor");
|
|
|
81
81
|
var CODEX_DIR = join(HOME, ".codex");
|
|
82
82
|
var OPENCLAW_DIR = join(HOME, ".openclaw");
|
|
83
83
|
var AGENTS_DIR = join(HOME, ".agents");
|
|
84
|
+
var CLAUDE_PROJECTS_DIR = join(CLAUDE_DIR, "projects");
|
|
85
|
+
var CODEX_SESSIONS_DIR = join(CODEX_DIR, "sessions");
|
|
84
86
|
var CLAUDE_SKILLS_DIR = join(CLAUDE_DIR, "skills");
|
|
85
87
|
var CLAUDE_ORGX_SKILL_DIR = join(CLAUDE_SKILLS_DIR, "orgx");
|
|
86
88
|
var CLAUDE_ORGX_SKILL_PATH = join(CLAUDE_ORGX_SKILL_DIR, "SKILL.md");
|
|
@@ -1335,6 +1337,44 @@ function parsePeopleFirstCapture(value) {
|
|
|
1335
1337
|
entries
|
|
1336
1338
|
};
|
|
1337
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
|
+
}
|
|
1338
1378
|
function createWizardState(now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
1339
1379
|
return {
|
|
1340
1380
|
installationId: `wizard-${randomUUID()}`,
|
|
@@ -1350,6 +1390,7 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1350
1390
|
const onboardingTask = parseOnboardingTask(record.onboardingTask);
|
|
1351
1391
|
const skillFiles = parseSkillFiles(record.skillFiles);
|
|
1352
1392
|
const peopleFirstCapture = parsePeopleFirstCapture(record.peopleFirstCapture);
|
|
1393
|
+
const dailyBriefOnboarding = parseDailyBriefOnboarding(record.dailyBriefOnboarding);
|
|
1353
1394
|
return {
|
|
1354
1395
|
installationId: record.installationId.trim(),
|
|
1355
1396
|
createdAt: record.createdAt.trim(),
|
|
@@ -1360,7 +1401,8 @@ function sanitizeWizardStateRecord(record) {
|
|
|
1360
1401
|
...firstValueInitiative ? { firstValueInitiative } : {},
|
|
1361
1402
|
...onboardingTask ? { onboardingTask } : {},
|
|
1362
1403
|
...skillFiles ? { skillFiles } : {},
|
|
1363
|
-
...peopleFirstCapture ? { peopleFirstCapture } : {}
|
|
1404
|
+
...peopleFirstCapture ? { peopleFirstCapture } : {},
|
|
1405
|
+
...dailyBriefOnboarding ? { dailyBriefOnboarding } : {}
|
|
1364
1406
|
};
|
|
1365
1407
|
}
|
|
1366
1408
|
function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
@@ -1389,8 +1431,33 @@ function readWizardState(statePath = ORGX_WIZARD_STATE_PATH) {
|
|
|
1389
1431
|
if (skillFiles !== void 0) state.skillFiles = skillFiles;
|
|
1390
1432
|
const peopleFirstCapture = parsePeopleFirstCapture(parsed.peopleFirstCapture);
|
|
1391
1433
|
if (peopleFirstCapture !== void 0) state.peopleFirstCapture = peopleFirstCapture;
|
|
1434
|
+
const dailyBriefOnboarding = parseDailyBriefOnboarding(parsed.dailyBriefOnboarding);
|
|
1435
|
+
if (dailyBriefOnboarding !== void 0) {
|
|
1436
|
+
state.dailyBriefOnboarding = dailyBriefOnboarding;
|
|
1437
|
+
}
|
|
1392
1438
|
return state;
|
|
1393
1439
|
}
|
|
1440
|
+
function getDailyBriefOnboardingDecision(workspaceId, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1441
|
+
const state = readWizardState(statePath);
|
|
1442
|
+
return state?.dailyBriefOnboarding?.entries.find(
|
|
1443
|
+
(entry) => entry.workspaceId === workspaceId
|
|
1444
|
+
) ?? null;
|
|
1445
|
+
}
|
|
1446
|
+
function recordDailyBriefOnboardingDecision(entry, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1447
|
+
return updateWizardState((current) => {
|
|
1448
|
+
const existingEntries = current.dailyBriefOnboarding?.entries ?? [];
|
|
1449
|
+
const withoutExisting = existingEntries.filter(
|
|
1450
|
+
(e) => e.workspaceId !== entry.workspaceId
|
|
1451
|
+
);
|
|
1452
|
+
return {
|
|
1453
|
+
...current,
|
|
1454
|
+
dailyBriefOnboarding: {
|
|
1455
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1456
|
+
entries: [...withoutExisting, entry]
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
}, statePath);
|
|
1460
|
+
}
|
|
1394
1461
|
function writeWizardState(value, statePath = ORGX_WIZARD_STATE_PATH) {
|
|
1395
1462
|
const record = sanitizeWizardStateRecord(value);
|
|
1396
1463
|
writeJsonFile(statePath, record, { mode: 384 });
|
|
@@ -4102,8 +4169,8 @@ function encodeRepoPath2(value) {
|
|
|
4102
4169
|
return value.split("/").filter((segment) => segment.length > 0).map((segment) => encodeURIComponent(segment)).join("/");
|
|
4103
4170
|
}
|
|
4104
4171
|
function isLikelyRepoFilePath(path) {
|
|
4105
|
-
const
|
|
4106
|
-
return
|
|
4172
|
+
const basename3 = path.split("/").pop() ?? path;
|
|
4173
|
+
return basename3.includes(".") && !/^\.[^./]+$/.test(basename3);
|
|
4107
4174
|
}
|
|
4108
4175
|
function buildContentsUrl2(spec, path) {
|
|
4109
4176
|
const encodedPath = encodeRepoPath2(path);
|
|
@@ -5102,6 +5169,14 @@ async function runWorkspaceSetup(client, prompts, options) {
|
|
|
5102
5169
|
}
|
|
5103
5170
|
return createAndSelectWorkspace(client, prompts);
|
|
5104
5171
|
}
|
|
5172
|
+
if (options.skipIfConfigured && currentWorkspace) {
|
|
5173
|
+
return {
|
|
5174
|
+
defaultChanged: false,
|
|
5175
|
+
message: `Using "${currentWorkspace.name}" as the default OrgX workspace.`,
|
|
5176
|
+
status: "unchanged",
|
|
5177
|
+
workspace: currentWorkspace
|
|
5178
|
+
};
|
|
5179
|
+
}
|
|
5105
5180
|
const initialWorkspaceId = currentWorkspace?.id ?? workspaces.find((workspace) => workspace.isDefault)?.id ?? workspaces[0]?.id;
|
|
5106
5181
|
const selected = await prompts.select({
|
|
5107
5182
|
message: "Choose the OrgX workspace this machine should use by default.",
|
|
@@ -5742,20 +5817,73 @@ var BASELINE_PROMPTS = [
|
|
|
5742
5817
|
{ task_type: "launch_post", label: "Launch post", placeholder: "60" },
|
|
5743
5818
|
{ task_type: "architecture_doc", label: "Architecture doc", placeholder: "90" }
|
|
5744
5819
|
];
|
|
5820
|
+
var DAILY_BRIEF_SETUP_CHOICES = {
|
|
5821
|
+
defaults: "defaults",
|
|
5822
|
+
customize: "customize",
|
|
5823
|
+
skip: "skip"
|
|
5824
|
+
};
|
|
5825
|
+
function buildDefaultBaselines() {
|
|
5826
|
+
return BASELINE_PROMPTS.map((bp) => ({
|
|
5827
|
+
task_type: bp.task_type,
|
|
5828
|
+
minutes: Number.parseInt(bp.placeholder, 10),
|
|
5829
|
+
confidence: 0.4
|
|
5830
|
+
}));
|
|
5831
|
+
}
|
|
5832
|
+
function buildDefaultGoals() {
|
|
5833
|
+
return [
|
|
5834
|
+
{
|
|
5835
|
+
goal_type: "time_saved_weekly",
|
|
5836
|
+
target_value: 180,
|
|
5837
|
+
unit: "minutes",
|
|
5838
|
+
period: "weekly"
|
|
5839
|
+
}
|
|
5840
|
+
];
|
|
5841
|
+
}
|
|
5842
|
+
function normalizeSendTime(value) {
|
|
5843
|
+
return value.trim().length === 4 ? `0${value.trim()}` : value.trim();
|
|
5844
|
+
}
|
|
5845
|
+
function recordSkipped(workspace, statePath) {
|
|
5846
|
+
recordDailyBriefOnboardingDecision(
|
|
5847
|
+
{
|
|
5848
|
+
workspaceId: workspace.id,
|
|
5849
|
+
workspaceName: workspace.name,
|
|
5850
|
+
status: "skipped",
|
|
5851
|
+
skippedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5852
|
+
},
|
|
5853
|
+
statePath
|
|
5854
|
+
);
|
|
5855
|
+
return {
|
|
5856
|
+
status: "skipped_user",
|
|
5857
|
+
message: "Daily Brief setup skipped. Run `wizard setup --daily-brief` when ready."
|
|
5858
|
+
};
|
|
5859
|
+
}
|
|
5745
5860
|
async function runDailyBriefOnboarding(options) {
|
|
5746
|
-
if (!options.interactive) {
|
|
5747
|
-
return {
|
|
5748
|
-
status: "skipped_non_interactive",
|
|
5749
|
-
message: "Daily Brief onboarding skipped \u2014 not attached to a TTY."
|
|
5750
|
-
};
|
|
5751
|
-
}
|
|
5752
5861
|
if (!options.workspace) {
|
|
5753
5862
|
return {
|
|
5754
5863
|
status: "skipped_no_workspace",
|
|
5755
5864
|
message: "Daily Brief onboarding skipped \u2014 no workspace resolved."
|
|
5756
5865
|
};
|
|
5757
5866
|
}
|
|
5758
|
-
|
|
5867
|
+
if (options.skip) {
|
|
5868
|
+
return recordSkipped(options.workspace, options.statePath);
|
|
5869
|
+
}
|
|
5870
|
+
const localDecision = getDailyBriefOnboardingDecision(
|
|
5871
|
+
options.workspace.id,
|
|
5872
|
+
options.statePath
|
|
5873
|
+
);
|
|
5874
|
+
if (!options.force && localDecision) {
|
|
5875
|
+
return {
|
|
5876
|
+
status: "skipped_already_completed",
|
|
5877
|
+
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."
|
|
5878
|
+
};
|
|
5879
|
+
}
|
|
5880
|
+
if (!options.interactive) {
|
|
5881
|
+
return {
|
|
5882
|
+
status: "skipped_non_interactive",
|
|
5883
|
+
message: "Daily Brief onboarding skipped \u2014 not attached to a TTY."
|
|
5884
|
+
};
|
|
5885
|
+
}
|
|
5886
|
+
const auth = await resolveOrgxAuth(options.authOptions);
|
|
5759
5887
|
if (!auth) {
|
|
5760
5888
|
return {
|
|
5761
5889
|
status: "failed",
|
|
@@ -5767,6 +5895,15 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5767
5895
|
if (state) {
|
|
5768
5896
|
const row = state.workspaces.find((w) => w.id === options.workspace.id);
|
|
5769
5897
|
if (row?.onboardingCompletedAt) {
|
|
5898
|
+
recordDailyBriefOnboardingDecision(
|
|
5899
|
+
{
|
|
5900
|
+
workspaceId: options.workspace.id,
|
|
5901
|
+
workspaceName: options.workspace.name,
|
|
5902
|
+
status: "completed",
|
|
5903
|
+
completedAt: row.onboardingCompletedAt
|
|
5904
|
+
},
|
|
5905
|
+
options.statePath
|
|
5906
|
+
);
|
|
5770
5907
|
return {
|
|
5771
5908
|
status: "skipped_already_completed",
|
|
5772
5909
|
message: "Daily Brief onboarding already completed for this workspace."
|
|
@@ -5774,93 +5911,116 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5774
5911
|
}
|
|
5775
5912
|
}
|
|
5776
5913
|
const { prompts } = options;
|
|
5777
|
-
const
|
|
5778
|
-
message: "
|
|
5779
|
-
initialValue:
|
|
5914
|
+
const setupChoice = await prompts.select({
|
|
5915
|
+
message: "Daily Brief setup",
|
|
5916
|
+
initialValue: DAILY_BRIEF_SETUP_CHOICES.defaults,
|
|
5917
|
+
options: [
|
|
5918
|
+
{
|
|
5919
|
+
value: DAILY_BRIEF_SETUP_CHOICES.defaults,
|
|
5920
|
+
label: "Use defaults",
|
|
5921
|
+
hint: "20m code review, 45m PRD, 07:00 daily."
|
|
5922
|
+
},
|
|
5923
|
+
{
|
|
5924
|
+
value: DAILY_BRIEF_SETUP_CHOICES.customize,
|
|
5925
|
+
label: "Customize",
|
|
5926
|
+
hint: "Answer baseline and delivery questions."
|
|
5927
|
+
},
|
|
5928
|
+
{
|
|
5929
|
+
value: DAILY_BRIEF_SETUP_CHOICES.skip,
|
|
5930
|
+
label: "Skip",
|
|
5931
|
+
hint: "Do not ask again unless you pass --daily-brief."
|
|
5932
|
+
}
|
|
5933
|
+
]
|
|
5780
5934
|
});
|
|
5781
|
-
if (prompts.isCancel(
|
|
5935
|
+
if (prompts.isCancel(setupChoice)) {
|
|
5782
5936
|
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5783
5937
|
}
|
|
5784
|
-
if (
|
|
5785
|
-
return
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5938
|
+
if (setupChoice === DAILY_BRIEF_SETUP_CHOICES.skip) {
|
|
5939
|
+
return recordSkipped(options.workspace, options.statePath);
|
|
5940
|
+
}
|
|
5941
|
+
const shouldCustomize = setupChoice === DAILY_BRIEF_SETUP_CHOICES.customize;
|
|
5942
|
+
const baselines = shouldCustomize ? [] : buildDefaultBaselines();
|
|
5943
|
+
if (shouldCustomize) {
|
|
5944
|
+
for (const bp of BASELINE_PROMPTS) {
|
|
5945
|
+
const answer = await prompts.text({
|
|
5946
|
+
message: `${bp.label} minutes`,
|
|
5947
|
+
placeholder: bp.placeholder,
|
|
5948
|
+
validate(value) {
|
|
5949
|
+
if (!value || value.trim() === "") return void 0;
|
|
5950
|
+
const n = Number.parseInt(value, 10);
|
|
5951
|
+
if (!Number.isFinite(n) || n <= 0 || n > 24 * 60) {
|
|
5952
|
+
return "Enter 1-1440 or leave blank.";
|
|
5953
|
+
}
|
|
5954
|
+
return void 0;
|
|
5955
|
+
}
|
|
5956
|
+
});
|
|
5957
|
+
if (prompts.isCancel(answer)) {
|
|
5958
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5959
|
+
}
|
|
5960
|
+
if (typeof answer === "string" && answer.trim() !== "") {
|
|
5961
|
+
const minutes = Number.parseInt(answer, 10);
|
|
5962
|
+
if (Number.isFinite(minutes) && minutes > 0) {
|
|
5963
|
+
baselines.push({ task_type: bp.task_type, minutes, confidence: 0.5 });
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5789
5967
|
}
|
|
5790
|
-
const
|
|
5791
|
-
|
|
5792
|
-
const
|
|
5793
|
-
message:
|
|
5794
|
-
placeholder:
|
|
5968
|
+
const goals = shouldCustomize ? [] : buildDefaultGoals();
|
|
5969
|
+
if (shouldCustomize) {
|
|
5970
|
+
const goalAnswer = await prompts.text({
|
|
5971
|
+
message: "Weekly time-saved target minutes",
|
|
5972
|
+
placeholder: "180",
|
|
5795
5973
|
validate(value) {
|
|
5796
5974
|
if (!value || value.trim() === "") return void 0;
|
|
5797
5975
|
const n = Number.parseInt(value, 10);
|
|
5798
|
-
if (!Number.isFinite(n) || n <= 0
|
|
5799
|
-
return "Enter
|
|
5976
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
5977
|
+
return "Enter a positive number or leave blank.";
|
|
5800
5978
|
}
|
|
5801
5979
|
return void 0;
|
|
5802
5980
|
}
|
|
5803
5981
|
});
|
|
5804
|
-
if (prompts.isCancel(
|
|
5982
|
+
if (prompts.isCancel(goalAnswer)) {
|
|
5805
5983
|
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5806
5984
|
}
|
|
5807
|
-
if (typeof
|
|
5808
|
-
const
|
|
5809
|
-
if (Number.isFinite(
|
|
5810
|
-
|
|
5985
|
+
if (typeof goalAnswer === "string" && goalAnswer.trim() !== "") {
|
|
5986
|
+
const target = Number.parseInt(goalAnswer, 10);
|
|
5987
|
+
if (Number.isFinite(target) && target > 0) {
|
|
5988
|
+
goals.push({
|
|
5989
|
+
goal_type: "time_saved_weekly",
|
|
5990
|
+
target_value: target,
|
|
5991
|
+
unit: "minutes",
|
|
5992
|
+
period: "weekly"
|
|
5993
|
+
});
|
|
5811
5994
|
}
|
|
5812
5995
|
}
|
|
5813
5996
|
}
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5997
|
+
let sendTimeLocal = "07:00";
|
|
5998
|
+
let onlyOnAttention = false;
|
|
5999
|
+
if (shouldCustomize) {
|
|
6000
|
+
const sendTimeAnswer = await prompts.text({
|
|
6001
|
+
message: "Daily brief time (HH:MM)",
|
|
6002
|
+
placeholder: "07:00",
|
|
6003
|
+
validate(value) {
|
|
6004
|
+
if (!value || value.trim() === "") return void 0;
|
|
6005
|
+
if (!/^\d{1,2}:\d{2}$/.test(value.trim())) {
|
|
6006
|
+
return "Use HH:MM (24h).";
|
|
6007
|
+
}
|
|
6008
|
+
return void 0;
|
|
5823
6009
|
}
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
if (prompts.isCancel(goalAnswer)) {
|
|
5828
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5829
|
-
}
|
|
5830
|
-
if (typeof goalAnswer === "string" && goalAnswer.trim() !== "") {
|
|
5831
|
-
const target = Number.parseInt(goalAnswer, 10);
|
|
5832
|
-
if (Number.isFinite(target) && target > 0) {
|
|
5833
|
-
goals.push({
|
|
5834
|
-
goal_type: "time_saved_weekly",
|
|
5835
|
-
target_value: target,
|
|
5836
|
-
unit: "minutes",
|
|
5837
|
-
period: "weekly"
|
|
5838
|
-
});
|
|
6010
|
+
});
|
|
6011
|
+
if (prompts.isCancel(sendTimeAnswer)) {
|
|
6012
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5839
6013
|
}
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
return "Use HH:MM (24h).";
|
|
5848
|
-
}
|
|
5849
|
-
return void 0;
|
|
6014
|
+
sendTimeLocal = typeof sendTimeAnswer === "string" && sendTimeAnswer.trim() ? normalizeSendTime(sendTimeAnswer) : "07:00";
|
|
6015
|
+
const onlyOnAttentionAnswer = await prompts.confirm({
|
|
6016
|
+
message: "Email only when attention is needed?",
|
|
6017
|
+
initialValue: false
|
|
6018
|
+
});
|
|
6019
|
+
if (prompts.isCancel(onlyOnAttentionAnswer)) {
|
|
6020
|
+
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5850
6021
|
}
|
|
5851
|
-
|
|
5852
|
-
if (prompts.isCancel(sendTimeAnswer)) {
|
|
5853
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
5854
|
-
}
|
|
5855
|
-
const sendTimeLocal = typeof sendTimeAnswer === "string" && sendTimeAnswer.trim() ? sendTimeAnswer.trim().length === 4 ? `0${sendTimeAnswer.trim()}` : sendTimeAnswer.trim() : "07:00";
|
|
5856
|
-
const onlyOnAttentionAnswer = await prompts.confirm({
|
|
5857
|
-
message: "Only email when something needs your attention?",
|
|
5858
|
-
initialValue: false
|
|
5859
|
-
});
|
|
5860
|
-
if (prompts.isCancel(onlyOnAttentionAnswer)) {
|
|
5861
|
-
return { status: "cancelled", message: "Daily Brief onboarding cancelled." };
|
|
6022
|
+
onlyOnAttention = Boolean(onlyOnAttentionAnswer);
|
|
5862
6023
|
}
|
|
5863
|
-
const onlyOnAttention = Boolean(onlyOnAttentionAnswer);
|
|
5864
6024
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
5865
6025
|
const commitPayload = {
|
|
5866
6026
|
workspace_id: options.workspace.id,
|
|
@@ -5902,6 +6062,15 @@ async function runDailyBriefOnboarding(options) {
|
|
|
5902
6062
|
}
|
|
5903
6063
|
const commitBody = await commitResponse.json().catch(() => ({}));
|
|
5904
6064
|
const previewUrl = typeof commitBody.daily_brief_preview_url === "string" ? commitBody.daily_brief_preview_url : "/today?mode=preview";
|
|
6065
|
+
recordDailyBriefOnboardingDecision(
|
|
6066
|
+
{
|
|
6067
|
+
workspaceId: options.workspace.id,
|
|
6068
|
+
workspaceName: options.workspace.name,
|
|
6069
|
+
status: "completed",
|
|
6070
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6071
|
+
},
|
|
6072
|
+
options.statePath
|
|
6073
|
+
);
|
|
5905
6074
|
return {
|
|
5906
6075
|
status: "completed",
|
|
5907
6076
|
message: "Your Daily Brief is configured. First brief lands tomorrow.",
|
|
@@ -5927,6 +6096,177 @@ async function fetchOnboardingState(auth) {
|
|
|
5927
6096
|
}
|
|
5928
6097
|
}
|
|
5929
6098
|
|
|
6099
|
+
// src/lib/ai-session-import.ts
|
|
6100
|
+
import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync3 } from "fs";
|
|
6101
|
+
import { basename as basename2, join as join4, relative as relative2 } from "path";
|
|
6102
|
+
var AI_SESSION_SOURCES = ["codex", "claude"];
|
|
6103
|
+
var DEFAULT_LIMIT_PER_SOURCE = 3;
|
|
6104
|
+
var DEFAULT_SINCE_DAYS = 30;
|
|
6105
|
+
var DEFAULT_MAX_BYTES_PER_FILE = 1e6;
|
|
6106
|
+
var AUDIT_RELEVANT_LINE_PATTERN = /\b(decision|decided|artifact|receipt|proof|commitment|committed|next action|follow[- ]?up|outcome|result|impact|roi|economics|token|cost|saved|open loop|gap|blocker|risk|owner|dri|writeback|rollback|quality score)\b/i;
|
|
6107
|
+
function parseAiSessionSources(value) {
|
|
6108
|
+
if (!value?.trim()) return [];
|
|
6109
|
+
const requested = value.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
|
|
6110
|
+
const expanded = requested.includes("all") ? [...AI_SESSION_SOURCES] : requested;
|
|
6111
|
+
const deduped = [...new Set(expanded)];
|
|
6112
|
+
const invalid = deduped.filter((source) => !AI_SESSION_SOURCES.includes(source));
|
|
6113
|
+
if (invalid.length > 0) {
|
|
6114
|
+
throw new Error(`Unsupported AI-session source: ${invalid.join(", ")}. Use codex, claude, or all.`);
|
|
6115
|
+
}
|
|
6116
|
+
return deduped;
|
|
6117
|
+
}
|
|
6118
|
+
function parseJsonLine(line) {
|
|
6119
|
+
try {
|
|
6120
|
+
return JSON.parse(line);
|
|
6121
|
+
} catch {
|
|
6122
|
+
return null;
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
function asText(value) {
|
|
6126
|
+
if (typeof value === "string") return value;
|
|
6127
|
+
if (Array.isArray(value)) {
|
|
6128
|
+
return value.map((item) => {
|
|
6129
|
+
if (typeof item === "string") return item;
|
|
6130
|
+
if (!isRecord(item)) return "";
|
|
6131
|
+
if (typeof item.text === "string") return item.text;
|
|
6132
|
+
if (typeof item.content === "string") return item.content;
|
|
6133
|
+
return "";
|
|
6134
|
+
}).filter(Boolean).join("\n");
|
|
6135
|
+
}
|
|
6136
|
+
if (isRecord(value) && typeof value.text === "string") return value.text;
|
|
6137
|
+
return "";
|
|
6138
|
+
}
|
|
6139
|
+
function extractCodexMessageText(record) {
|
|
6140
|
+
if (!isRecord(record) || record.type !== "response_item" || !isRecord(record.payload)) {
|
|
6141
|
+
return "";
|
|
6142
|
+
}
|
|
6143
|
+
const payload = record.payload;
|
|
6144
|
+
if (payload.type !== "message" || payload.role !== "user" && payload.role !== "assistant") {
|
|
6145
|
+
return "";
|
|
6146
|
+
}
|
|
6147
|
+
return asText(payload.content);
|
|
6148
|
+
}
|
|
6149
|
+
function extractClaudeMessageText(record) {
|
|
6150
|
+
if (!isRecord(record) || record.isMeta === true || !isRecord(record.message)) {
|
|
6151
|
+
return "";
|
|
6152
|
+
}
|
|
6153
|
+
const message = record.message;
|
|
6154
|
+
if (message.role !== "user" && message.role !== "assistant") {
|
|
6155
|
+
return "";
|
|
6156
|
+
}
|
|
6157
|
+
const text2 = asText(message.content);
|
|
6158
|
+
if (/^<local-command-caveat>/i.test(text2.trim())) return "";
|
|
6159
|
+
return text2;
|
|
6160
|
+
}
|
|
6161
|
+
function keepAuditRelevantLines(text2) {
|
|
6162
|
+
return text2.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && AUDIT_RELEVANT_LINE_PATTERN.test(line));
|
|
6163
|
+
}
|
|
6164
|
+
function collectJsonlFiles(root, source) {
|
|
6165
|
+
if (!existsSync5(root)) return [];
|
|
6166
|
+
const files = [];
|
|
6167
|
+
const stack = [root];
|
|
6168
|
+
while (stack.length > 0) {
|
|
6169
|
+
const current = stack.pop();
|
|
6170
|
+
if (!current) continue;
|
|
6171
|
+
let entries;
|
|
6172
|
+
try {
|
|
6173
|
+
entries = readdirSync3(current);
|
|
6174
|
+
} catch {
|
|
6175
|
+
continue;
|
|
6176
|
+
}
|
|
6177
|
+
for (const entry of entries) {
|
|
6178
|
+
const path = join4(current, entry);
|
|
6179
|
+
let stats;
|
|
6180
|
+
try {
|
|
6181
|
+
stats = statSync3(path);
|
|
6182
|
+
} catch {
|
|
6183
|
+
continue;
|
|
6184
|
+
}
|
|
6185
|
+
if (stats.isDirectory()) {
|
|
6186
|
+
stack.push(path);
|
|
6187
|
+
continue;
|
|
6188
|
+
}
|
|
6189
|
+
if (stats.isFile() && path.endsWith(".jsonl")) {
|
|
6190
|
+
files.push({ mtimeMs: stats.mtimeMs, path, source });
|
|
6191
|
+
}
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
return files;
|
|
6195
|
+
}
|
|
6196
|
+
function readSessionImport(candidate, root, options) {
|
|
6197
|
+
let stats;
|
|
6198
|
+
try {
|
|
6199
|
+
stats = statSync3(candidate.path);
|
|
6200
|
+
} catch {
|
|
6201
|
+
return null;
|
|
6202
|
+
}
|
|
6203
|
+
if (stats.size > options.maxBytesPerFile) return null;
|
|
6204
|
+
const extractor = candidate.source === "codex" ? extractCodexMessageText : extractClaudeMessageText;
|
|
6205
|
+
const lines = readFileSync3(candidate.path, "utf8").split(/\r?\n/);
|
|
6206
|
+
const relevantLines = [];
|
|
6207
|
+
for (const line of lines) {
|
|
6208
|
+
const record = parseJsonLine(line);
|
|
6209
|
+
const text2 = extractor(record);
|
|
6210
|
+
if (!text2) continue;
|
|
6211
|
+
relevantLines.push(...keepAuditRelevantLines(text2));
|
|
6212
|
+
}
|
|
6213
|
+
const deduped = [...new Set(relevantLines)].slice(0, 80);
|
|
6214
|
+
if (deduped.length === 0) return null;
|
|
6215
|
+
const relativePath = relative2(root, candidate.path);
|
|
6216
|
+
return {
|
|
6217
|
+
sourceId: `${candidate.source}:${basename2(candidate.path, ".jsonl")}`,
|
|
6218
|
+
sourceLabel: `${candidate.source === "codex" ? "Codex" : "Claude"} session ${relativePath}`,
|
|
6219
|
+
text: deduped.join("\n")
|
|
6220
|
+
};
|
|
6221
|
+
}
|
|
6222
|
+
function loadAiSessionImports(options) {
|
|
6223
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
6224
|
+
const sinceMs = now.getTime() - (options.sinceDays ?? DEFAULT_SINCE_DAYS) * 24 * 60 * 60 * 1e3;
|
|
6225
|
+
const limitPerSource = Math.max(1, options.limitPerSource ?? DEFAULT_LIMIT_PER_SOURCE);
|
|
6226
|
+
const maxBytesPerFile = Math.max(1, options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE);
|
|
6227
|
+
const roots = {
|
|
6228
|
+
claude: options.claudeProjectsDir ?? CLAUDE_PROJECTS_DIR,
|
|
6229
|
+
codex: options.codexSessionsDir ?? CODEX_SESSIONS_DIR
|
|
6230
|
+
};
|
|
6231
|
+
const imports = [];
|
|
6232
|
+
const connectedSources = [];
|
|
6233
|
+
const missingSources = [];
|
|
6234
|
+
let scannedFiles = 0;
|
|
6235
|
+
let skippedFiles = 0;
|
|
6236
|
+
for (const source of options.sources) {
|
|
6237
|
+
const root = roots[source];
|
|
6238
|
+
const candidates = collectJsonlFiles(root, source).filter((file) => file.mtimeMs >= sinceMs).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
6239
|
+
if (candidates.length === 0) {
|
|
6240
|
+
missingSources.push(`${source} session store`);
|
|
6241
|
+
continue;
|
|
6242
|
+
}
|
|
6243
|
+
let importedForSource = 0;
|
|
6244
|
+
for (const candidate of candidates) {
|
|
6245
|
+
if (importedForSource >= limitPerSource) break;
|
|
6246
|
+
scannedFiles += 1;
|
|
6247
|
+
const imported = readSessionImport(candidate, root, { maxBytesPerFile });
|
|
6248
|
+
if (!imported) {
|
|
6249
|
+
skippedFiles += 1;
|
|
6250
|
+
continue;
|
|
6251
|
+
}
|
|
6252
|
+
imports.push(imported);
|
|
6253
|
+
importedForSource += 1;
|
|
6254
|
+
}
|
|
6255
|
+
if (importedForSource > 0) {
|
|
6256
|
+
connectedSources.push(`${source === "codex" ? "Codex" : "Claude"} local sessions`);
|
|
6257
|
+
} else {
|
|
6258
|
+
missingSources.push(`${source} audit-relevant session lines`);
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6261
|
+
return {
|
|
6262
|
+
connectedSources,
|
|
6263
|
+
imports,
|
|
6264
|
+
missingSources,
|
|
6265
|
+
scannedFiles,
|
|
6266
|
+
skippedFiles
|
|
6267
|
+
};
|
|
6268
|
+
}
|
|
6269
|
+
|
|
5930
6270
|
// src/lib/self-audit.ts
|
|
5931
6271
|
import { createHash as createHash3 } from "crypto";
|
|
5932
6272
|
var SELF_AUDIT_SCHEMA_VERSION = "2026-04-27";
|
|
@@ -6529,10 +6869,10 @@ function formatScoreLine(scores) {
|
|
|
6529
6869
|
}
|
|
6530
6870
|
function readAuditInput(options, interactive) {
|
|
6531
6871
|
if (options.input?.trim()) {
|
|
6532
|
-
return
|
|
6872
|
+
return readFileSync4(resolve(options.input.trim()), "utf8");
|
|
6533
6873
|
}
|
|
6534
6874
|
if (!process.stdin.isTTY) {
|
|
6535
|
-
return
|
|
6875
|
+
return readFileSync4(0, "utf8");
|
|
6536
6876
|
}
|
|
6537
6877
|
if (!interactive) {
|
|
6538
6878
|
throw new Error("Audit input is required. Pass --input <file> or pipe text into wizard audit.");
|
|
@@ -6549,6 +6889,53 @@ function readAuditInput(options, interactive) {
|
|
|
6549
6889
|
return value;
|
|
6550
6890
|
});
|
|
6551
6891
|
}
|
|
6892
|
+
function parsePositiveInteger(value, fallback, label) {
|
|
6893
|
+
if (!value?.trim()) return fallback;
|
|
6894
|
+
const parsed = Number.parseInt(value.trim(), 10);
|
|
6895
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
6896
|
+
throw new Error(`${label} must be a positive integer.`);
|
|
6897
|
+
}
|
|
6898
|
+
return parsed;
|
|
6899
|
+
}
|
|
6900
|
+
async function readAuditImports(options, interactive) {
|
|
6901
|
+
const sources = parseAiSessionSources(options.from);
|
|
6902
|
+
const imports = [];
|
|
6903
|
+
const connectedSources = [];
|
|
6904
|
+
const missingSources = [];
|
|
6905
|
+
if (sources.length > 0) {
|
|
6906
|
+
const imported = loadAiSessionImports({
|
|
6907
|
+
...options.claudeProjectsDir?.trim() ? { claudeProjectsDir: resolve(options.claudeProjectsDir.trim()) } : {},
|
|
6908
|
+
...options.codexSessionsDir?.trim() ? { codexSessionsDir: resolve(options.codexSessionsDir.trim()) } : {},
|
|
6909
|
+
limitPerSource: parsePositiveInteger(options.sessionLimit, 3, "--session-limit"),
|
|
6910
|
+
sinceDays: parsePositiveInteger(options.sessionDays, 30, "--session-days"),
|
|
6911
|
+
sources
|
|
6912
|
+
});
|
|
6913
|
+
imports.push(...imported.imports);
|
|
6914
|
+
connectedSources.push(...imported.connectedSources);
|
|
6915
|
+
missingSources.push(...imported.missingSources);
|
|
6916
|
+
}
|
|
6917
|
+
const shouldReadManualInput = Boolean(options.input?.trim()) || sources.length === 0 || !process.stdin.isTTY;
|
|
6918
|
+
if (shouldReadManualInput) {
|
|
6919
|
+
const text2 = (await readAuditInput(options, interactive)).trim();
|
|
6920
|
+
if (text2) {
|
|
6921
|
+
imports.push({
|
|
6922
|
+
sourceId: "wizard-audit-input",
|
|
6923
|
+
sourceLabel: options.sourceLabel?.trim() || "Wizard audit input",
|
|
6924
|
+
text: text2
|
|
6925
|
+
});
|
|
6926
|
+
connectedSources.push(options.sourceLabel?.trim() || "Manual AI-session import");
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6929
|
+
if (imports.length === 0) {
|
|
6930
|
+
const sourceHint = sources.length > 0 ? ` No audit-relevant lines were found in ${sources.join(", ")} sessions.` : "";
|
|
6931
|
+
throw new Error(`Audit input is required.${sourceHint} Pass --input <file>, pipe text, or use --from codex|claude|all.`);
|
|
6932
|
+
}
|
|
6933
|
+
return {
|
|
6934
|
+
connectedSources,
|
|
6935
|
+
imports,
|
|
6936
|
+
missingSources
|
|
6937
|
+
};
|
|
6938
|
+
}
|
|
6552
6939
|
function requireWriteApproval(options, interactive) {
|
|
6553
6940
|
const wantsWrite = Boolean(options.createInitiative || options.attachToInitiative || options.writeFollowUp);
|
|
6554
6941
|
if (!wantsWrite || options.yes || options.dryRun) return true;
|
|
@@ -6591,23 +6978,19 @@ async function resolveAuditWorkspace(options) {
|
|
|
6591
6978
|
}
|
|
6592
6979
|
async function runAuditCommand(options) {
|
|
6593
6980
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
6594
|
-
const
|
|
6595
|
-
if (!text2) return;
|
|
6981
|
+
const auditImports = await readAuditImports(options, interactive);
|
|
6596
6982
|
const workspace = await resolveAuditWorkspace(options);
|
|
6597
6983
|
const plan = buildSelfAuditPlan({
|
|
6598
6984
|
connectedSources: [
|
|
6599
|
-
|
|
6985
|
+
...auditImports.connectedSources,
|
|
6600
6986
|
...workspace.id === "local-workspace" ? [] : ["OrgX workspace"]
|
|
6601
6987
|
],
|
|
6602
6988
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6603
|
-
imports:
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
text: text2
|
|
6608
|
-
}
|
|
6989
|
+
imports: auditImports.imports,
|
|
6990
|
+
missingSources: [
|
|
6991
|
+
...workspace.id === "local-workspace" ? ["OrgX workspace auth"] : [],
|
|
6992
|
+
...auditImports.missingSources
|
|
6609
6993
|
],
|
|
6610
|
-
missingSources: workspace.id === "local-workspace" ? ["OrgX workspace auth", "automatic AI-session import"] : ["automatic AI-session import"],
|
|
6611
6994
|
workspace
|
|
6612
6995
|
});
|
|
6613
6996
|
const markdown = renderSelfAuditMarkdown(plan);
|
|
@@ -7580,13 +7963,16 @@ function printDoctorReport(report, assessment) {
|
|
|
7580
7963
|
async function main() {
|
|
7581
7964
|
const program = new Command();
|
|
7582
7965
|
program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
|
|
7583
|
-
const pkgVersion = true ? "0.1.
|
|
7966
|
+
const pkgVersion = true ? "0.1.24" : void 0;
|
|
7584
7967
|
program.version(pkgVersion ?? "unknown", "-V, --version");
|
|
7585
7968
|
program.hook("preAction", () => {
|
|
7586
7969
|
console.log(renderBanner(pkgVersion));
|
|
7587
7970
|
});
|
|
7588
|
-
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) => {
|
|
7971
|
+
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) => {
|
|
7589
7972
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
7973
|
+
if (options.dailyBrief && options.skipDailyBrief) {
|
|
7974
|
+
throw new Error("Use either --daily-brief or --skip-daily-brief, not both.");
|
|
7975
|
+
}
|
|
7590
7976
|
await safeTrackWizardTelemetry("wizard_started", {
|
|
7591
7977
|
command: "setup",
|
|
7592
7978
|
interactive,
|
|
@@ -7752,7 +8138,8 @@ async function main() {
|
|
|
7752
8138
|
text: textPrompt
|
|
7753
8139
|
},
|
|
7754
8140
|
{
|
|
7755
|
-
interactive
|
|
8141
|
+
interactive,
|
|
8142
|
+
skipIfConfigured: !options.workspace
|
|
7756
8143
|
}
|
|
7757
8144
|
);
|
|
7758
8145
|
if (workspaceSetup.status === "cancelled") {
|
|
@@ -7790,7 +8177,9 @@ async function main() {
|
|
|
7790
8177
|
console.log(` ${ICON.ok} ${pc3.green("workspace ")} ${pc3.bold(workspaceSetup.workspace.name)}`);
|
|
7791
8178
|
}
|
|
7792
8179
|
const briefResult = await runDailyBriefOnboarding({
|
|
8180
|
+
force: Boolean(options.dailyBrief),
|
|
7793
8181
|
interactive,
|
|
8182
|
+
skip: Boolean(options.skipDailyBrief),
|
|
7794
8183
|
workspace: resolvedWorkspace,
|
|
7795
8184
|
prompts: {
|
|
7796
8185
|
cancel: clack.cancel,
|
|
@@ -7802,6 +8191,8 @@ async function main() {
|
|
|
7802
8191
|
});
|
|
7803
8192
|
if (briefResult.status === "cancelled") {
|
|
7804
8193
|
console.log(` ${ICON.skip} ${pc3.dim(briefResult.message)}`);
|
|
8194
|
+
} else if (briefResult.status === "skipped_user") {
|
|
8195
|
+
console.log(` ${ICON.skip} ${pc3.dim(briefResult.message)}`);
|
|
7805
8196
|
} else if (briefResult.status === "completed") {
|
|
7806
8197
|
console.log(` ${ICON.ok} ${pc3.green("daily brief")} ${pc3.dim(briefResult.message)}`);
|
|
7807
8198
|
} else if (briefResult.status === "failed") {
|
|
@@ -8242,7 +8633,7 @@ async function main() {
|
|
|
8242
8633
|
jsonOutput: Boolean(options.json)
|
|
8243
8634
|
});
|
|
8244
8635
|
});
|
|
8245
|
-
program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
|
|
8636
|
+
program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "3").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for audit import").option("--claude-projects-dir <path>", "override Claude projects directory for audit import").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
|
|
8246
8637
|
await safeTrackWizardTelemetry("audit_started", {
|
|
8247
8638
|
attach_to_initiative: Boolean(options.attachToInitiative),
|
|
8248
8639
|
command: "audit",
|