@cleocode/cleo 2026.5.131 → 2026.5.133
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/index.js +1064 -539
- package/dist/cli/index.js.map +3 -3
- package/package.json +12 -11
- package/scripts/install-daemon-service.mjs +59 -12
package/dist/cli/index.js
CHANGED
|
@@ -27495,6 +27495,70 @@ function iterationCapFor(node, runtimeDefault) {
|
|
|
27495
27495
|
if (typeof cap === "number" && Number.isFinite(cap) && cap >= 0) return cap;
|
|
27496
27496
|
return runtimeDefault;
|
|
27497
27497
|
}
|
|
27498
|
+
function validateDecompositionTaskTree(nodeId, taskTree2) {
|
|
27499
|
+
if (!Array.isArray(taskTree2)) {
|
|
27500
|
+
return `ensures.schema[task_tree] on ${nodeId}: task_tree must be a non-empty array, got ${typeof taskTree2}`;
|
|
27501
|
+
}
|
|
27502
|
+
if (taskTree2.length === 0) {
|
|
27503
|
+
return `ensures.schema[task_tree] on ${nodeId}: task_tree is an empty array \u2014 decomposition produced no tasks`;
|
|
27504
|
+
}
|
|
27505
|
+
const knownIds = /* @__PURE__ */ new Set();
|
|
27506
|
+
for (const entry of taskTree2) {
|
|
27507
|
+
if (typeof entry.id === "string") {
|
|
27508
|
+
knownIds.add(entry.id);
|
|
27509
|
+
}
|
|
27510
|
+
}
|
|
27511
|
+
for (let i = 0; i < taskTree2.length; i++) {
|
|
27512
|
+
const entry = taskTree2[i];
|
|
27513
|
+
if (typeof entry !== "object" || entry === null) {
|
|
27514
|
+
return `ensures.schema[task_tree] on ${nodeId}: entry[${i}] must be an object, got ${entry === null ? "null" : typeof entry}`;
|
|
27515
|
+
}
|
|
27516
|
+
if (typeof entry.title !== "string" || entry.title.trim().length === 0) {
|
|
27517
|
+
return `ensures.schema[task_tree] on ${nodeId}: entry[${i}].title must be a non-empty string`;
|
|
27518
|
+
}
|
|
27519
|
+
if (!Array.isArray(entry.acceptance) || entry.acceptance.length === 0) {
|
|
27520
|
+
return `ensures.schema[task_tree] on ${nodeId}: entry[${i}] ("${entry.title}") must have a non-empty acceptance array`;
|
|
27521
|
+
}
|
|
27522
|
+
const hasValidAc = entry.acceptance.some(
|
|
27523
|
+
(ac) => typeof ac === "string" && ac.trim().length > 0
|
|
27524
|
+
);
|
|
27525
|
+
if (!hasValidAc) {
|
|
27526
|
+
return `ensures.schema[task_tree] on ${nodeId}: entry[${i}] ("${entry.title}") acceptance array contains no non-empty strings`;
|
|
27527
|
+
}
|
|
27528
|
+
if (Array.isArray(entry.depends) && knownIds.size > 0) {
|
|
27529
|
+
for (const depId of entry.depends) {
|
|
27530
|
+
if (typeof depId === "string" && /^T\d{3,}$/.test(depId) && !knownIds.has(depId)) {
|
|
27531
|
+
}
|
|
27532
|
+
}
|
|
27533
|
+
}
|
|
27534
|
+
}
|
|
27535
|
+
return null;
|
|
27536
|
+
}
|
|
27537
|
+
function validateIvtrEvidenceOutput(nodeId, evidence) {
|
|
27538
|
+
if (evidence === null || evidence === void 0) {
|
|
27539
|
+
return `ensures.schema[evidence] on ${nodeId}: evidence must be present (non-null, non-undefined)`;
|
|
27540
|
+
}
|
|
27541
|
+
if (typeof evidence === "string") {
|
|
27542
|
+
if (evidence.trim().length === 0) {
|
|
27543
|
+
return `ensures.schema[evidence] on ${nodeId}: evidence string must not be empty`;
|
|
27544
|
+
}
|
|
27545
|
+
return null;
|
|
27546
|
+
}
|
|
27547
|
+
if (Array.isArray(evidence)) {
|
|
27548
|
+
if (evidence.length === 0) {
|
|
27549
|
+
return `ensures.schema[evidence] on ${nodeId}: evidence array must not be empty`;
|
|
27550
|
+
}
|
|
27551
|
+
return null;
|
|
27552
|
+
}
|
|
27553
|
+
if (typeof evidence === "object") {
|
|
27554
|
+
const keys = Object.keys(evidence);
|
|
27555
|
+
if (keys.length === 0) {
|
|
27556
|
+
return `ensures.schema[evidence] on ${nodeId}: evidence object must have at least one key (got {})`;
|
|
27557
|
+
}
|
|
27558
|
+
return null;
|
|
27559
|
+
}
|
|
27560
|
+
return `ensures.schema[evidence] on ${nodeId}: evidence must be a string, array, or object (got ${typeof evidence})`;
|
|
27561
|
+
}
|
|
27498
27562
|
async function runFromNode(args) {
|
|
27499
27563
|
const {
|
|
27500
27564
|
db,
|
|
@@ -27593,6 +27657,39 @@ async function runFromNode(args) {
|
|
|
27593
27657
|
}
|
|
27594
27658
|
}
|
|
27595
27659
|
}
|
|
27660
|
+
if (node.ensures?.schema) {
|
|
27661
|
+
let schemaViolation = null;
|
|
27662
|
+
if (node.ensures.schema === "task_tree") {
|
|
27663
|
+
schemaViolation = validateDecompositionTaskTree(node.id, context["task_tree"]);
|
|
27664
|
+
} else if (node.ensures.schema === "evidence") {
|
|
27665
|
+
schemaViolation = validateIvtrEvidenceOutput(node.id, context["evidence"]);
|
|
27666
|
+
}
|
|
27667
|
+
if (schemaViolation !== null) {
|
|
27668
|
+
auditContractViolation(
|
|
27669
|
+
args.projectRoot,
|
|
27670
|
+
run.runId,
|
|
27671
|
+
node.id,
|
|
27672
|
+
"ensures",
|
|
27673
|
+
node.ensures.schema,
|
|
27674
|
+
playbook.name
|
|
27675
|
+
);
|
|
27676
|
+
const handled = handleContractErrorHandler(
|
|
27677
|
+
playbook,
|
|
27678
|
+
"contract_violation",
|
|
27679
|
+
schemaViolation
|
|
27680
|
+
);
|
|
27681
|
+
if (handled === "abort") {
|
|
27682
|
+
failedNodeId = node.id;
|
|
27683
|
+
lastError = schemaViolation;
|
|
27684
|
+
} else {
|
|
27685
|
+
context["__ensuresSchemaViolation"] = schemaViolation;
|
|
27686
|
+
if (handled === "hitl_escalate") {
|
|
27687
|
+
exceededNodeId = node.id;
|
|
27688
|
+
}
|
|
27689
|
+
}
|
|
27690
|
+
}
|
|
27691
|
+
}
|
|
27692
|
+
if (failedNodeId !== void 0) break;
|
|
27596
27693
|
const nextId = resolveNextNodeId(node.id, edgeIndex);
|
|
27597
27694
|
if (nextId !== null) {
|
|
27598
27695
|
const edge = resolveEdge(node.id, nextId, playbook.edges);
|
|
@@ -27908,6 +28005,8 @@ __export(src_exports, {
|
|
|
27908
28005
|
resumePlaybook: () => resumePlaybook,
|
|
27909
28006
|
updatePlaybookApproval: () => updatePlaybookApproval,
|
|
27910
28007
|
updatePlaybookRun: () => updatePlaybookRun,
|
|
28008
|
+
validateDecompositionTaskTree: () => validateDecompositionTaskTree,
|
|
28009
|
+
validateIvtrEvidenceOutput: () => validateIvtrEvidenceOutput,
|
|
27911
28010
|
validatePlaybookCompliance: () => validatePlaybookCompliance
|
|
27912
28011
|
});
|
|
27913
28012
|
var PLAYBOOKS_PACKAGE_VERSION;
|
|
@@ -27974,8 +28073,8 @@ async function loadPlaybookByName(name) {
|
|
|
27974
28073
|
return null;
|
|
27975
28074
|
}
|
|
27976
28075
|
try {
|
|
27977
|
-
const { getProjectRoot:
|
|
27978
|
-
const projectRoot = __playbookRuntimeOverrides.projectRoot ??
|
|
28076
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
|
|
28077
|
+
const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot58();
|
|
27979
28078
|
const resolved = resolvePlaybook(name, {
|
|
27980
28079
|
projectRoot,
|
|
27981
28080
|
globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
|
|
@@ -28019,8 +28118,8 @@ async function acquireDb() {
|
|
|
28019
28118
|
async function buildDefaultDispatcher() {
|
|
28020
28119
|
if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
|
|
28021
28120
|
const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
|
|
28022
|
-
const { getProjectRoot:
|
|
28023
|
-
const projectRoot =
|
|
28121
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
|
|
28122
|
+
const projectRoot = getProjectRoot58();
|
|
28024
28123
|
return {
|
|
28025
28124
|
async dispatch(input2) {
|
|
28026
28125
|
try {
|
|
@@ -28210,8 +28309,8 @@ var init_playbook2 = __esm({
|
|
|
28210
28309
|
projectRoot = __playbookRuntimeOverrides.projectRoot;
|
|
28211
28310
|
} else {
|
|
28212
28311
|
try {
|
|
28213
|
-
const { getProjectRoot:
|
|
28214
|
-
projectRoot =
|
|
28312
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
|
|
28313
|
+
projectRoot = getProjectRoot58();
|
|
28215
28314
|
} catch {
|
|
28216
28315
|
projectRoot = void 0;
|
|
28217
28316
|
}
|
|
@@ -28275,14 +28374,14 @@ var init_playbook2 = __esm({
|
|
|
28275
28374
|
const dispatcher = await buildDefaultDispatcher();
|
|
28276
28375
|
let result;
|
|
28277
28376
|
try {
|
|
28278
|
-
const { getProjectRoot:
|
|
28377
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
|
|
28279
28378
|
const opts = {
|
|
28280
28379
|
db,
|
|
28281
28380
|
playbook: parsed.definition,
|
|
28282
28381
|
playbookHash: parsed.sourceHash,
|
|
28283
28382
|
initialContext,
|
|
28284
28383
|
dispatcher,
|
|
28285
|
-
projectRoot:
|
|
28384
|
+
projectRoot: getProjectRoot58()
|
|
28286
28385
|
};
|
|
28287
28386
|
if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
|
|
28288
28387
|
opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
|
|
@@ -28523,7 +28622,7 @@ async function orchestrateAnalyzeOp(params) {
|
|
|
28523
28622
|
return orchestrateAnalyze(params.epicId, getProjectRoot11(), params.mode);
|
|
28524
28623
|
}
|
|
28525
28624
|
async function orchestrateClassifyOp(params) {
|
|
28526
|
-
return orchestrateClassify(params.request, params.context, getProjectRoot11());
|
|
28625
|
+
return orchestrateClassify(params.request, params.context, getProjectRoot11(), params.taskId);
|
|
28527
28626
|
}
|
|
28528
28627
|
function orchestrateFanoutStatusOp(params) {
|
|
28529
28628
|
const entry = fanoutManifestStore.get(params.manifestEntryId);
|
|
@@ -28672,7 +28771,69 @@ async function orchestrateApproveOp(params) {
|
|
|
28672
28771
|
async function orchestrateRejectOp(params) {
|
|
28673
28772
|
return Promise.resolve({ success: true, data: params });
|
|
28674
28773
|
}
|
|
28675
|
-
async function orchestrateClassify(request, context, projectRoot) {
|
|
28774
|
+
async function orchestrateClassify(request, context, projectRoot, taskId) {
|
|
28775
|
+
if (taskId) {
|
|
28776
|
+
try {
|
|
28777
|
+
const { getDb: getDb3 } = await import("@cleocode/core/internal");
|
|
28778
|
+
const { tasks } = await import("@cleocode/core/store/tasks-schema");
|
|
28779
|
+
const { eq: eq2 } = await import("drizzle-orm");
|
|
28780
|
+
const { classifyTask: classifyTask2 } = await import("@cleocode/core");
|
|
28781
|
+
const db = await getDb3(projectRoot);
|
|
28782
|
+
const row = await db.select().from(tasks).where(eq2(tasks.id, taskId)).get();
|
|
28783
|
+
if (!row) {
|
|
28784
|
+
return {
|
|
28785
|
+
success: false,
|
|
28786
|
+
error: {
|
|
28787
|
+
code: "E_NOT_FOUND",
|
|
28788
|
+
message: `Task ${taskId} not found`
|
|
28789
|
+
}
|
|
28790
|
+
};
|
|
28791
|
+
}
|
|
28792
|
+
const task = {
|
|
28793
|
+
id: row.id,
|
|
28794
|
+
title: row.title,
|
|
28795
|
+
description: row.description ?? "",
|
|
28796
|
+
status: row.status,
|
|
28797
|
+
priority: row.priority ?? "medium",
|
|
28798
|
+
type: row.type ?? void 0,
|
|
28799
|
+
kind: row.kind ?? void 0,
|
|
28800
|
+
size: row.size ?? void 0,
|
|
28801
|
+
labels: (() => {
|
|
28802
|
+
try {
|
|
28803
|
+
const parsed = JSON.parse(row.labelsJson ?? "[]");
|
|
28804
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
28805
|
+
} catch {
|
|
28806
|
+
return [];
|
|
28807
|
+
}
|
|
28808
|
+
})(),
|
|
28809
|
+
createdAt: row.createdAt
|
|
28810
|
+
};
|
|
28811
|
+
const result = classifyTask2(task);
|
|
28812
|
+
return {
|
|
28813
|
+
success: true,
|
|
28814
|
+
data: {
|
|
28815
|
+
team: result.agentId,
|
|
28816
|
+
lead: result.role === "lead" ? result.agentId : null,
|
|
28817
|
+
protocol: result.role,
|
|
28818
|
+
stage: null,
|
|
28819
|
+
confidence: result.confidence,
|
|
28820
|
+
reasoning: result.warning ? `${result.reason} | warning: ${result.warning}` : result.reason
|
|
28821
|
+
}
|
|
28822
|
+
};
|
|
28823
|
+
} catch (error) {
|
|
28824
|
+
getLogger8("domain:orchestrate").error(
|
|
28825
|
+
{ operation: "classify", taskId, err: error },
|
|
28826
|
+
error instanceof Error ? error.message : String(error)
|
|
28827
|
+
);
|
|
28828
|
+
return {
|
|
28829
|
+
success: false,
|
|
28830
|
+
error: {
|
|
28831
|
+
code: "E_CLASSIFY_FAILED",
|
|
28832
|
+
message: error instanceof Error ? error.message : String(error)
|
|
28833
|
+
}
|
|
28834
|
+
};
|
|
28835
|
+
}
|
|
28836
|
+
}
|
|
28676
28837
|
try {
|
|
28677
28838
|
const { getCleoCantWorkflowsDir } = await import("@cleocode/core/internal");
|
|
28678
28839
|
const { readFileSync: readFileSync22, readdirSync: readdirSync3, existsSync: existsSync21 } = await import("node:fs");
|
|
@@ -28734,6 +28895,9 @@ async function orchestrateClassify(request, context, projectRoot) {
|
|
|
28734
28895
|
}
|
|
28735
28896
|
matches.sort((a, b) => b.score - a.score);
|
|
28736
28897
|
const best = matches[0];
|
|
28898
|
+
const allHintWords = best.consultWhen.toLowerCase().split(/\s+/).filter(Boolean);
|
|
28899
|
+
const normalised = allHintWords.length > 0 ? Math.min(best.score / allHintWords.length, 1) : 0;
|
|
28900
|
+
const confidence = best.score > 0 ? Math.max(normalised, 0.5) : 0.1;
|
|
28737
28901
|
return {
|
|
28738
28902
|
success: true,
|
|
28739
28903
|
data: {
|
|
@@ -28741,7 +28905,7 @@ async function orchestrateClassify(request, context, projectRoot) {
|
|
|
28741
28905
|
lead: null,
|
|
28742
28906
|
protocol: "base-subagent",
|
|
28743
28907
|
stage: best.stages[0] ?? null,
|
|
28744
|
-
confidence
|
|
28908
|
+
confidence,
|
|
28745
28909
|
reasoning: best.score > 0 ? `Matched team '${best.team}' via consult-when hint: "${best.consultWhen}"` : `No strong match found; defaulting to first registered team '${best.team}'`
|
|
28746
28910
|
}
|
|
28747
28911
|
};
|
|
@@ -34920,11 +35084,11 @@ var init_security = __esm({
|
|
|
34920
35084
|
});
|
|
34921
35085
|
|
|
34922
35086
|
// packages/cleo/src/dispatch/middleware/sanitizer.ts
|
|
34923
|
-
function createSanitizer(
|
|
35087
|
+
function createSanitizer(getProjectRoot58) {
|
|
34924
35088
|
return async (req, next) => {
|
|
34925
35089
|
if (req.params) {
|
|
34926
35090
|
try {
|
|
34927
|
-
const root =
|
|
35091
|
+
const root = getProjectRoot58 ? getProjectRoot58() : void 0;
|
|
34928
35092
|
req.params = sanitizeParams(req.params, root, {
|
|
34929
35093
|
domain: req.domain,
|
|
34930
35094
|
operation: req.operation
|
|
@@ -40725,9 +40889,9 @@ var init_backup = __esm({
|
|
|
40725
40889
|
async run({ args }) {
|
|
40726
40890
|
const scope = args.scope;
|
|
40727
40891
|
const { packBundle } = await import("@cleocode/core/store/backup-pack.js");
|
|
40728
|
-
const { getProjectRoot:
|
|
40892
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
40729
40893
|
const includesProject = scope === "project" || scope === "all";
|
|
40730
|
-
const projectRoot = includesProject ?
|
|
40894
|
+
const projectRoot = includesProject ? getProjectRoot58() : void 0;
|
|
40731
40895
|
let passphrase;
|
|
40732
40896
|
if (args.encrypt === true) {
|
|
40733
40897
|
passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
|
|
@@ -40803,12 +40967,12 @@ var init_backup = __esm({
|
|
|
40803
40967
|
},
|
|
40804
40968
|
async run({ args }) {
|
|
40805
40969
|
const bundlePath = args.bundle;
|
|
40806
|
-
const { getProjectRoot:
|
|
40970
|
+
const { getProjectRoot: getProjectRoot58, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
|
|
40807
40971
|
const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
|
|
40808
40972
|
const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
|
|
40809
40973
|
const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
|
|
40810
40974
|
const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
|
|
40811
|
-
const projectRoot =
|
|
40975
|
+
const projectRoot = getProjectRoot58();
|
|
40812
40976
|
if (args.force !== true) {
|
|
40813
40977
|
const existing = checkForExistingData(projectRoot, getCleoHome6());
|
|
40814
40978
|
if (existing.length > 0) {
|
|
@@ -43107,6 +43271,108 @@ var init_claim = __esm({
|
|
|
43107
43271
|
}
|
|
43108
43272
|
});
|
|
43109
43273
|
|
|
43274
|
+
// packages/cleo/src/cli/commands/classify.ts
|
|
43275
|
+
var classify_exports = {};
|
|
43276
|
+
__export(classify_exports, {
|
|
43277
|
+
classifyCommand: () => classifyCommand
|
|
43278
|
+
});
|
|
43279
|
+
import { classifyReadiness, classifyTask, getProjectRoot as getProjectRoot31 } from "@cleocode/core";
|
|
43280
|
+
var classifyCommand;
|
|
43281
|
+
var init_classify = __esm({
|
|
43282
|
+
"packages/cleo/src/cli/commands/classify.ts"() {
|
|
43283
|
+
"use strict";
|
|
43284
|
+
init_define_cli_command();
|
|
43285
|
+
init_renderers();
|
|
43286
|
+
classifyCommand = defineCommand({
|
|
43287
|
+
meta: {
|
|
43288
|
+
name: "classify",
|
|
43289
|
+
description: "Classify a task: readiness verdict (proceed|grill) + persona routing (agent, confidence)"
|
|
43290
|
+
},
|
|
43291
|
+
args: {
|
|
43292
|
+
taskId: {
|
|
43293
|
+
type: "positional",
|
|
43294
|
+
description: "Task ID to classify (e.g. T1234)",
|
|
43295
|
+
required: true
|
|
43296
|
+
}
|
|
43297
|
+
},
|
|
43298
|
+
async run({ args }) {
|
|
43299
|
+
const taskId = args.taskId;
|
|
43300
|
+
const projectRoot = getProjectRoot31();
|
|
43301
|
+
const { getDb: getDb3 } = await import("@cleocode/core/store/sqlite.js");
|
|
43302
|
+
const { tasks } = await import("@cleocode/core/store/tasks-schema");
|
|
43303
|
+
const { eq: eq2 } = await import("drizzle-orm");
|
|
43304
|
+
const db = await getDb3(projectRoot);
|
|
43305
|
+
const row = await db.select().from(tasks).where(eq2(tasks.id, taskId)).get();
|
|
43306
|
+
if (!row) {
|
|
43307
|
+
cliOutput(
|
|
43308
|
+
{
|
|
43309
|
+
success: false,
|
|
43310
|
+
error: { code: "E_NOT_FOUND", message: `Task ${taskId} not found` }
|
|
43311
|
+
},
|
|
43312
|
+
{ command: "classify", operation: "classify.show" }
|
|
43313
|
+
);
|
|
43314
|
+
return;
|
|
43315
|
+
}
|
|
43316
|
+
const labels = (() => {
|
|
43317
|
+
try {
|
|
43318
|
+
const parsed = JSON.parse(row.labelsJson ?? "[]");
|
|
43319
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
43320
|
+
} catch {
|
|
43321
|
+
return [];
|
|
43322
|
+
}
|
|
43323
|
+
})();
|
|
43324
|
+
const acceptance = (() => {
|
|
43325
|
+
try {
|
|
43326
|
+
const parsed = JSON.parse(row.acceptanceJson ?? "[]");
|
|
43327
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
43328
|
+
} catch {
|
|
43329
|
+
return [];
|
|
43330
|
+
}
|
|
43331
|
+
})();
|
|
43332
|
+
const task = {
|
|
43333
|
+
id: row.id,
|
|
43334
|
+
title: row.title,
|
|
43335
|
+
description: row.description ?? "",
|
|
43336
|
+
status: row.status,
|
|
43337
|
+
priority: row.priority ?? "medium",
|
|
43338
|
+
type: row.type ?? void 0,
|
|
43339
|
+
kind: row.kind ?? void 0,
|
|
43340
|
+
size: row.size ?? void 0,
|
|
43341
|
+
pipelineStage: row.pipelineStage ?? void 0,
|
|
43342
|
+
blockedBy: row.blockedBy ?? void 0,
|
|
43343
|
+
phase: row.phase ?? void 0,
|
|
43344
|
+
scope: row.scope ?? void 0,
|
|
43345
|
+
labels,
|
|
43346
|
+
acceptance,
|
|
43347
|
+
createdAt: row.createdAt
|
|
43348
|
+
};
|
|
43349
|
+
const readiness = classifyReadiness(task);
|
|
43350
|
+
const routing = classifyTask(task);
|
|
43351
|
+
cliOutput(
|
|
43352
|
+
{
|
|
43353
|
+
taskId: row.id,
|
|
43354
|
+
title: row.title,
|
|
43355
|
+
readiness: {
|
|
43356
|
+
verdict: readiness.verdict,
|
|
43357
|
+
reason: readiness.reason,
|
|
43358
|
+
triggers: readiness.triggers
|
|
43359
|
+
},
|
|
43360
|
+
routing: {
|
|
43361
|
+
agentId: routing.agentId,
|
|
43362
|
+
role: routing.role,
|
|
43363
|
+
confidence: routing.confidence,
|
|
43364
|
+
reason: routing.reason,
|
|
43365
|
+
usedFallback: routing.usedFallback,
|
|
43366
|
+
warning: routing.warning
|
|
43367
|
+
}
|
|
43368
|
+
},
|
|
43369
|
+
{ command: "classify", operation: "classify.show" }
|
|
43370
|
+
);
|
|
43371
|
+
}
|
|
43372
|
+
});
|
|
43373
|
+
}
|
|
43374
|
+
});
|
|
43375
|
+
|
|
43110
43376
|
// packages/cleo/src/cli/commands/code.ts
|
|
43111
43377
|
var code_exports = {};
|
|
43112
43378
|
__export(code_exports, {
|
|
@@ -43939,7 +44205,7 @@ var init_conduit3 = __esm({
|
|
|
43939
44205
|
});
|
|
43940
44206
|
|
|
43941
44207
|
// packages/cleo/src/cli/commands/config/drift-check.ts
|
|
43942
|
-
import { getProjectRoot as
|
|
44208
|
+
import { getProjectRoot as getProjectRoot32 } from "@cleocode/core";
|
|
43943
44209
|
import { checkDrift } from "@cleocode/core/config/registry";
|
|
43944
44210
|
function parseDriftScope(raw) {
|
|
43945
44211
|
const value = raw ?? "project";
|
|
@@ -43984,7 +44250,7 @@ var init_drift_check = __esm({
|
|
|
43984
44250
|
}
|
|
43985
44251
|
let driftResult;
|
|
43986
44252
|
try {
|
|
43987
|
-
const projectRoot =
|
|
44253
|
+
const projectRoot = getProjectRoot32();
|
|
43988
44254
|
driftResult = await checkDrift(scope, projectRoot);
|
|
43989
44255
|
} catch (err) {
|
|
43990
44256
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -44012,7 +44278,7 @@ var init_drift_check = __esm({
|
|
|
44012
44278
|
});
|
|
44013
44279
|
|
|
44014
44280
|
// packages/cleo/src/cli/commands/config/get.ts
|
|
44015
|
-
import { getProjectRoot as
|
|
44281
|
+
import { getProjectRoot as getProjectRoot33 } from "@cleocode/core";
|
|
44016
44282
|
import { getConfigValue } from "@cleocode/core/config/registry";
|
|
44017
44283
|
function parseResolveScope(raw) {
|
|
44018
44284
|
const value = raw ?? "merged";
|
|
@@ -44070,7 +44336,7 @@ var init_get = __esm({
|
|
|
44070
44336
|
}
|
|
44071
44337
|
let value;
|
|
44072
44338
|
try {
|
|
44073
|
-
const projectRoot =
|
|
44339
|
+
const projectRoot = getProjectRoot33();
|
|
44074
44340
|
value = await getConfigValue(key, { scope, projectRoot });
|
|
44075
44341
|
} catch (err) {
|
|
44076
44342
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -44099,7 +44365,7 @@ var init_get = __esm({
|
|
|
44099
44365
|
});
|
|
44100
44366
|
|
|
44101
44367
|
// packages/cleo/src/cli/commands/config/set.ts
|
|
44102
|
-
import { getProjectRoot as
|
|
44368
|
+
import { getProjectRoot as getProjectRoot34, parseConfigValue, setConfigValue } from "@cleocode/core";
|
|
44103
44369
|
import { validateConfig as validateConfig2 } from "@cleocode/core/config/registry";
|
|
44104
44370
|
function parseWriteScope(raw) {
|
|
44105
44371
|
const value = raw ?? "project";
|
|
@@ -44209,7 +44475,7 @@ var init_set = __esm({
|
|
|
44209
44475
|
let written;
|
|
44210
44476
|
let validate;
|
|
44211
44477
|
try {
|
|
44212
|
-
const projectRoot =
|
|
44478
|
+
const projectRoot = getProjectRoot34();
|
|
44213
44479
|
written = await setConfigValue(key, coerced, projectRoot, {
|
|
44214
44480
|
global: scope === "global"
|
|
44215
44481
|
});
|
|
@@ -44241,7 +44507,7 @@ var init_set = __esm({
|
|
|
44241
44507
|
});
|
|
44242
44508
|
|
|
44243
44509
|
// packages/cleo/src/cli/commands/config/show.ts
|
|
44244
|
-
import { getProjectRoot as
|
|
44510
|
+
import { getProjectRoot as getProjectRoot35 } from "@cleocode/core";
|
|
44245
44511
|
import {
|
|
44246
44512
|
resolveCleoConfig
|
|
44247
44513
|
} from "@cleocode/core/config/registry";
|
|
@@ -44287,7 +44553,7 @@ var init_show = __esm({
|
|
|
44287
44553
|
return;
|
|
44288
44554
|
}
|
|
44289
44555
|
try {
|
|
44290
|
-
const projectRoot =
|
|
44556
|
+
const projectRoot = getProjectRoot35();
|
|
44291
44557
|
const config = await resolveCleoConfig({ scope, projectRoot });
|
|
44292
44558
|
const result = { scope, config };
|
|
44293
44559
|
cliOutput(result, {
|
|
@@ -44307,7 +44573,7 @@ var init_show = __esm({
|
|
|
44307
44573
|
});
|
|
44308
44574
|
|
|
44309
44575
|
// packages/cleo/src/cli/commands/config/validate.ts
|
|
44310
|
-
import { getProjectRoot as
|
|
44576
|
+
import { getProjectRoot as getProjectRoot36 } from "@cleocode/core";
|
|
44311
44577
|
import { validateConfig as validateConfig3 } from "@cleocode/core/config/registry";
|
|
44312
44578
|
function parseValidateScope(raw) {
|
|
44313
44579
|
const value = raw ?? "project";
|
|
@@ -44352,7 +44618,7 @@ var init_validate2 = __esm({
|
|
|
44352
44618
|
}
|
|
44353
44619
|
let validate;
|
|
44354
44620
|
try {
|
|
44355
|
-
const projectRoot =
|
|
44621
|
+
const projectRoot = getProjectRoot36();
|
|
44356
44622
|
validate = await validateConfig3(scope, projectRoot);
|
|
44357
44623
|
} catch (err) {
|
|
44358
44624
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -45169,22 +45435,40 @@ var init_daemon2 = __esm({
|
|
|
45169
45435
|
description: "Register the CLEO daemon as a user-level system service (systemd / launchd)"
|
|
45170
45436
|
},
|
|
45171
45437
|
args: {
|
|
45438
|
+
saga: {
|
|
45439
|
+
type: "string",
|
|
45440
|
+
description: "Scope the daemon to tasks within a Saga (sets CLEO_SENTIENT_SAGA in service env)",
|
|
45441
|
+
required: false
|
|
45442
|
+
},
|
|
45443
|
+
epic: {
|
|
45444
|
+
type: "string",
|
|
45445
|
+
description: "Scope the daemon to tasks directly under an Epic (sets CLEO_SENTIENT_EPIC in service env)",
|
|
45446
|
+
required: false
|
|
45447
|
+
},
|
|
45172
45448
|
json: {
|
|
45173
45449
|
type: "boolean",
|
|
45174
45450
|
description: "Output result as JSON"
|
|
45175
45451
|
}
|
|
45176
45452
|
},
|
|
45177
|
-
async run({ args
|
|
45453
|
+
async run({ args }) {
|
|
45178
45454
|
try {
|
|
45179
45455
|
const scriptPath = resolveDaemonInstallerScript();
|
|
45180
45456
|
const { installDaemonService } = await import(scriptPath);
|
|
45181
|
-
|
|
45457
|
+
const scopeSagaId = typeof args.saga === "string" && args.saga.length > 0 ? args.saga : void 0;
|
|
45458
|
+
const scopeEpicId = typeof args.epic === "string" && args.epic.length > 0 ? args.epic : void 0;
|
|
45459
|
+
await installDaemonService({ scopeSagaId, scopeEpicId });
|
|
45460
|
+
const scopeNote = scopeEpicId !== void 0 ? ` (scoped to epic ${scopeEpicId})` : scopeSagaId !== void 0 ? ` (scoped to saga ${scopeSagaId})` : "";
|
|
45182
45461
|
cliOutput(
|
|
45183
|
-
{
|
|
45462
|
+
{
|
|
45463
|
+
platform: process.platform,
|
|
45464
|
+
scopeSagaId,
|
|
45465
|
+
scopeEpicId,
|
|
45466
|
+
message: `Daemon service installation complete${scopeNote}.`
|
|
45467
|
+
},
|
|
45184
45468
|
{
|
|
45185
45469
|
command: "daemon",
|
|
45186
45470
|
operation: "daemon.install",
|
|
45187
|
-
message:
|
|
45471
|
+
message: `CLEO: Daemon service installation complete${scopeNote}.`
|
|
45188
45472
|
}
|
|
45189
45473
|
);
|
|
45190
45474
|
} catch (err) {
|
|
@@ -46875,7 +47159,7 @@ import { dirname as dirname7, join as join19, normalize, resolve as resolve4 } f
|
|
|
46875
47159
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
46876
47160
|
import {
|
|
46877
47161
|
createAttachmentStore as createAttachmentStore4,
|
|
46878
|
-
getProjectRoot as
|
|
47162
|
+
getProjectRoot as getProjectRoot37,
|
|
46879
47163
|
searchAllProjectDocs as searchAllProjectDocs2
|
|
46880
47164
|
} from "@cleocode/core/internal";
|
|
46881
47165
|
function getViewerAssetsDir() {
|
|
@@ -46935,7 +47219,7 @@ async function serveStatic(res, assetsDir, relPath) {
|
|
|
46935
47219
|
}
|
|
46936
47220
|
}
|
|
46937
47221
|
function buildViewerHandler(opts = {}) {
|
|
46938
|
-
const projectRoot = opts.projectRoot ??
|
|
47222
|
+
const projectRoot = opts.projectRoot ?? getProjectRoot37();
|
|
46939
47223
|
const assetsDir = getViewerAssetsDir();
|
|
46940
47224
|
const store = createAttachmentStore4();
|
|
46941
47225
|
return async (req, res) => {
|
|
@@ -47108,24 +47392,143 @@ var init_server = __esm({
|
|
|
47108
47392
|
}
|
|
47109
47393
|
});
|
|
47110
47394
|
|
|
47111
|
-
// packages/cleo/src/cli/
|
|
47112
|
-
import {
|
|
47113
|
-
import { open as fsOpen } from "node:fs/promises";
|
|
47395
|
+
// packages/cleo/src/cli/docs-viewer-subsystem.ts
|
|
47396
|
+
import { mkdir as mkdir2 } from "node:fs/promises";
|
|
47114
47397
|
import { join as join20 } from "node:path";
|
|
47115
|
-
import {
|
|
47116
|
-
import {
|
|
47117
|
-
function
|
|
47118
|
-
const
|
|
47119
|
-
return
|
|
47398
|
+
import { getCleoHome as getCleoHome3 } from "@cleocode/core";
|
|
47399
|
+
import { defineSubsystem } from "@cleocode/runtime/daemon";
|
|
47400
|
+
function getViewerPaths() {
|
|
47401
|
+
const cleoHome = getCleoHome3();
|
|
47402
|
+
return {
|
|
47403
|
+
pidFile: viewerPidFilePath(),
|
|
47404
|
+
logFile: join20(cleoHome, "viewer.log"),
|
|
47405
|
+
logDir: cleoHome
|
|
47406
|
+
};
|
|
47407
|
+
}
|
|
47408
|
+
function isViewerProcessRunning(pid) {
|
|
47409
|
+
return isProcessAlive(pid);
|
|
47120
47410
|
}
|
|
47121
|
-
async function
|
|
47122
|
-
const
|
|
47123
|
-
|
|
47124
|
-
|
|
47125
|
-
await
|
|
47411
|
+
async function getViewerStatus() {
|
|
47412
|
+
const record = await readViewerPidFile();
|
|
47413
|
+
if (!record) return { running: false, pid: null, port: null, host: null, url: null };
|
|
47414
|
+
if (!isProcessAlive(record.pid)) {
|
|
47415
|
+
await removeViewerPidFile();
|
|
47416
|
+
return { running: false, pid: null, port: null, host: null, url: null };
|
|
47126
47417
|
}
|
|
47127
|
-
return
|
|
47418
|
+
return {
|
|
47419
|
+
running: true,
|
|
47420
|
+
pid: record.pid,
|
|
47421
|
+
port: record.port,
|
|
47422
|
+
host: record.host,
|
|
47423
|
+
url: `http://${record.host}:${record.port}`
|
|
47424
|
+
};
|
|
47128
47425
|
}
|
|
47426
|
+
function createDocsViewerSubsystem(opts = {}) {
|
|
47427
|
+
const startPort = opts.startPort ?? VIEWER_DEFAULT_PORT;
|
|
47428
|
+
const endPort = opts.endPort ?? VIEWER_DEFAULT_END_PORT;
|
|
47429
|
+
const host = opts.host ?? VIEWER_DEFAULT_HOST;
|
|
47430
|
+
const autoIncrement = !(opts.noAutoPort ?? false);
|
|
47431
|
+
let live;
|
|
47432
|
+
return defineSubsystem({
|
|
47433
|
+
name: VIEWER_SUBSYSTEM_NAME,
|
|
47434
|
+
async start() {
|
|
47435
|
+
const { pidFile, logDir } = getViewerPaths();
|
|
47436
|
+
const existing = await getViewerStatus();
|
|
47437
|
+
if (existing.running && existing.pid !== null) {
|
|
47438
|
+
const ctx2 = {
|
|
47439
|
+
pid: existing.pid,
|
|
47440
|
+
pidFile,
|
|
47441
|
+
port: existing.port ?? startPort,
|
|
47442
|
+
host: existing.host ?? host
|
|
47443
|
+
};
|
|
47444
|
+
live = ctx2;
|
|
47445
|
+
return ctx2;
|
|
47446
|
+
}
|
|
47447
|
+
await mkdir2(logDir, { recursive: true });
|
|
47448
|
+
const handle = await startViewer({
|
|
47449
|
+
startPort,
|
|
47450
|
+
endPort,
|
|
47451
|
+
host,
|
|
47452
|
+
autoIncrement
|
|
47453
|
+
});
|
|
47454
|
+
await writeViewerPidFile({
|
|
47455
|
+
pid: process.pid,
|
|
47456
|
+
port: handle.port,
|
|
47457
|
+
host: handle.host,
|
|
47458
|
+
projectRoot: process.cwd(),
|
|
47459
|
+
startedAt: Date.now()
|
|
47460
|
+
});
|
|
47461
|
+
const ctx = {
|
|
47462
|
+
pid: process.pid,
|
|
47463
|
+
pidFile,
|
|
47464
|
+
port: handle.port,
|
|
47465
|
+
host: handle.host
|
|
47466
|
+
};
|
|
47467
|
+
live = ctx;
|
|
47468
|
+
return ctx;
|
|
47469
|
+
},
|
|
47470
|
+
healthProbe() {
|
|
47471
|
+
if (live === void 0) {
|
|
47472
|
+
const stopped = "stopped";
|
|
47473
|
+
return {
|
|
47474
|
+
child_id: VIEWER_SUBSYSTEM_NAME,
|
|
47475
|
+
pid: 0,
|
|
47476
|
+
state: stopped,
|
|
47477
|
+
restart_count: 0,
|
|
47478
|
+
detail: "not started"
|
|
47479
|
+
};
|
|
47480
|
+
}
|
|
47481
|
+
const alive = isViewerProcessRunning(live.pid);
|
|
47482
|
+
const state = alive ? "running" : "stopped";
|
|
47483
|
+
return {
|
|
47484
|
+
child_id: VIEWER_SUBSYSTEM_NAME,
|
|
47485
|
+
pid: alive ? live.pid : 0,
|
|
47486
|
+
state,
|
|
47487
|
+
restart_count: 0,
|
|
47488
|
+
detail: alive ? `url=http://${live.host}:${live.port} pid=${live.pid}` : `pid=${live.pid} exited`
|
|
47489
|
+
};
|
|
47490
|
+
},
|
|
47491
|
+
async shutdown(context) {
|
|
47492
|
+
if (!isViewerProcessRunning(context.pid)) {
|
|
47493
|
+
await removeViewerPidFile();
|
|
47494
|
+
live = void 0;
|
|
47495
|
+
return;
|
|
47496
|
+
}
|
|
47497
|
+
try {
|
|
47498
|
+
process.kill(context.pid, "SIGTERM");
|
|
47499
|
+
} catch {
|
|
47500
|
+
}
|
|
47501
|
+
for (let i = 0; i < SIGTERM_GRACE_ITERATIONS; i++) {
|
|
47502
|
+
if (!isViewerProcessRunning(context.pid)) break;
|
|
47503
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
47504
|
+
}
|
|
47505
|
+
if (isViewerProcessRunning(context.pid)) {
|
|
47506
|
+
try {
|
|
47507
|
+
process.kill(context.pid, "SIGKILL");
|
|
47508
|
+
} catch {
|
|
47509
|
+
}
|
|
47510
|
+
}
|
|
47511
|
+
await removeViewerPidFile();
|
|
47512
|
+
live = void 0;
|
|
47513
|
+
}
|
|
47514
|
+
});
|
|
47515
|
+
}
|
|
47516
|
+
var VIEWER_DEFAULT_PORT, VIEWER_DEFAULT_END_PORT, VIEWER_DEFAULT_HOST, VIEWER_SUBSYSTEM_NAME, SIGTERM_GRACE_ITERATIONS;
|
|
47517
|
+
var init_docs_viewer_subsystem = __esm({
|
|
47518
|
+
"packages/cleo/src/cli/docs-viewer-subsystem.ts"() {
|
|
47519
|
+
"use strict";
|
|
47520
|
+
init_pidfile();
|
|
47521
|
+
init_server();
|
|
47522
|
+
VIEWER_DEFAULT_PORT = 7777;
|
|
47523
|
+
VIEWER_DEFAULT_END_PORT = 7800;
|
|
47524
|
+
VIEWER_DEFAULT_HOST = "127.0.0.1";
|
|
47525
|
+
VIEWER_SUBSYSTEM_NAME = "cleo-docs-viewer";
|
|
47526
|
+
SIGTERM_GRACE_ITERATIONS = 20;
|
|
47527
|
+
}
|
|
47528
|
+
});
|
|
47529
|
+
|
|
47530
|
+
// packages/cleo/src/cli/commands/docs-viewer.ts
|
|
47531
|
+
import { spawn } from "node:child_process";
|
|
47129
47532
|
function openInBrowser(url) {
|
|
47130
47533
|
try {
|
|
47131
47534
|
let cmd;
|
|
@@ -47144,72 +47547,40 @@ function openInBrowser(url) {
|
|
|
47144
47547
|
} catch {
|
|
47145
47548
|
}
|
|
47146
47549
|
}
|
|
47147
|
-
|
|
47148
|
-
const logFile = join20(getCleoHome3(), "viewer.log");
|
|
47149
|
-
const handle = await fsOpen(logFile, "a").catch(() => null);
|
|
47150
|
-
const stdio = handle ? ["ignore", handle.fd, handle.fd] : ["ignore", "ignore", "ignore"];
|
|
47151
|
-
const args = [
|
|
47152
|
-
getCleoBinPath(),
|
|
47153
|
-
"docs",
|
|
47154
|
-
"serve",
|
|
47155
|
-
"--port",
|
|
47156
|
-
String(opts.startPort),
|
|
47157
|
-
"--end-port",
|
|
47158
|
-
String(opts.endPort),
|
|
47159
|
-
"--host",
|
|
47160
|
-
opts.host
|
|
47161
|
-
];
|
|
47162
|
-
if (opts.noAutoPort) args.push("--no-auto-port");
|
|
47163
|
-
const child = spawn(process.execPath, args, {
|
|
47164
|
-
detached: true,
|
|
47165
|
-
stdio,
|
|
47166
|
-
env: { ...process.env, [DETACHED_CHILD_ENV]: "1" },
|
|
47167
|
-
cwd: getProjectRoot37()
|
|
47168
|
-
});
|
|
47169
|
-
child.unref();
|
|
47170
|
-
if (handle) await handle.close();
|
|
47171
|
-
return child;
|
|
47172
|
-
}
|
|
47173
|
-
var DETACHED_CHILD_ENV, serveCommand, openCommand, stopCommand4, viewerStatusCommand, runViewerStatus, viewerCommand, docsViewerSubcommands;
|
|
47550
|
+
var serveCommand, openCommand, stopCommand4, viewerStatusCommand, runViewerStatus, viewerCommand, docsViewerSubcommands;
|
|
47174
47551
|
var init_docs_viewer = __esm({
|
|
47175
47552
|
"packages/cleo/src/cli/commands/docs-viewer.ts"() {
|
|
47176
47553
|
"use strict";
|
|
47177
47554
|
init_src2();
|
|
47178
47555
|
init_dist();
|
|
47179
47556
|
init_pidfile();
|
|
47180
|
-
|
|
47557
|
+
init_docs_viewer_subsystem();
|
|
47181
47558
|
init_renderers();
|
|
47182
|
-
DETACHED_CHILD_ENV = "CLEO_VIEWER_DETACHED_CHILD";
|
|
47183
47559
|
serveCommand = defineCommand({
|
|
47184
47560
|
meta: {
|
|
47185
47561
|
name: "serve",
|
|
47186
|
-
description: "
|
|
47562
|
+
description: "Run docs viewer \u2014 prefer `cleo docs viewer start`"
|
|
47187
47563
|
},
|
|
47188
47564
|
args: {
|
|
47189
47565
|
port: {
|
|
47190
47566
|
type: "string",
|
|
47191
47567
|
description: "Starting port (default 7777)",
|
|
47192
|
-
default:
|
|
47568
|
+
default: String(VIEWER_DEFAULT_PORT)
|
|
47193
47569
|
},
|
|
47194
47570
|
"end-port": {
|
|
47195
47571
|
type: "string",
|
|
47196
47572
|
description: "Last port to try when auto-incrementing (default 7800)",
|
|
47197
|
-
default:
|
|
47573
|
+
default: String(VIEWER_DEFAULT_END_PORT)
|
|
47198
47574
|
},
|
|
47199
47575
|
host: {
|
|
47200
47576
|
type: "string",
|
|
47201
47577
|
description: "Bind host (default 127.0.0.1)",
|
|
47202
|
-
default:
|
|
47578
|
+
default: VIEWER_DEFAULT_HOST
|
|
47203
47579
|
},
|
|
47204
47580
|
"no-auto-port": {
|
|
47205
47581
|
type: "boolean",
|
|
47206
47582
|
description: "Disable auto-increment when start port is busy",
|
|
47207
47583
|
default: false
|
|
47208
|
-
},
|
|
47209
|
-
detach: {
|
|
47210
|
-
type: "boolean",
|
|
47211
|
-
description: "Run in background; write pid to viewer.pid; exit immediately",
|
|
47212
|
-
default: false
|
|
47213
47584
|
}
|
|
47214
47585
|
},
|
|
47215
47586
|
async run({ args }) {
|
|
@@ -47217,8 +47588,6 @@ var init_docs_viewer = __esm({
|
|
|
47217
47588
|
const endPort = Number.parseInt(String(args["end-port"]), 10);
|
|
47218
47589
|
const host = String(args.host);
|
|
47219
47590
|
const noAutoPort = Boolean(args["no-auto-port"]);
|
|
47220
|
-
const detach = Boolean(args.detach);
|
|
47221
|
-
const isDetachedChild = process.env[DETACHED_CHILD_ENV] === "1";
|
|
47222
47591
|
if (!Number.isFinite(startPort) || startPort < 1 || startPort > 65535) {
|
|
47223
47592
|
cliError(`invalid --port: ${args.port}`, 6 /* VALIDATION_ERROR */, { name: "E_VALIDATION" });
|
|
47224
47593
|
return;
|
|
@@ -47229,79 +47598,25 @@ var init_docs_viewer = __esm({
|
|
|
47229
47598
|
});
|
|
47230
47599
|
return;
|
|
47231
47600
|
}
|
|
47232
|
-
|
|
47233
|
-
const
|
|
47234
|
-
|
|
47235
|
-
|
|
47236
|
-
{
|
|
47237
|
-
running: true,
|
|
47238
|
-
pid: existing.pid,
|
|
47239
|
-
port: existing.port,
|
|
47240
|
-
host: existing.host,
|
|
47241
|
-
url: `http://${existing.host}:${existing.port}`,
|
|
47242
|
-
pidFile: viewerPidFilePath()
|
|
47243
|
-
},
|
|
47244
|
-
{
|
|
47245
|
-
command: "docs serve",
|
|
47246
|
-
operation: "docs.serve",
|
|
47247
|
-
message: `viewer already running on http://${existing.host}:${existing.port}`
|
|
47248
|
-
}
|
|
47249
|
-
);
|
|
47250
|
-
return;
|
|
47251
|
-
}
|
|
47252
|
-
const child = await spawnDetachedServer({ startPort, endPort, host, noAutoPort });
|
|
47253
|
-
if (!child.pid) {
|
|
47254
|
-
cliError("failed to spawn detached viewer process", 1 /* GENERAL_ERROR */, {
|
|
47255
|
-
name: "E_SPAWN_FAILED"
|
|
47256
|
-
});
|
|
47257
|
-
return;
|
|
47258
|
-
}
|
|
47259
|
-
let record2 = null;
|
|
47260
|
-
const deadline = Date.now() + 1e4;
|
|
47261
|
-
while (Date.now() < deadline) {
|
|
47262
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
47263
|
-
record2 = await readViewerPidFile();
|
|
47264
|
-
if (record2 && record2.pid === child.pid) break;
|
|
47265
|
-
if (!isProcessAlive(child.pid)) {
|
|
47266
|
-
cliError(
|
|
47267
|
-
"detached viewer exited before binding (check ~/.local/share/cleo/viewer.log)",
|
|
47268
|
-
1 /* GENERAL_ERROR */,
|
|
47269
|
-
{ name: "E_VIEWER_EXITED" }
|
|
47270
|
-
);
|
|
47271
|
-
return;
|
|
47272
|
-
}
|
|
47273
|
-
}
|
|
47274
|
-
if (!record2 || record2.pid !== child.pid) {
|
|
47275
|
-
cliError("timed out waiting for detached viewer to bind", 1 /* GENERAL_ERROR */, {
|
|
47276
|
-
name: "E_VIEWER_TIMEOUT"
|
|
47277
|
-
});
|
|
47278
|
-
return;
|
|
47279
|
-
}
|
|
47601
|
+
try {
|
|
47602
|
+
const subsystem = createDocsViewerSubsystem({ startPort, endPort, host, noAutoPort });
|
|
47603
|
+
const ctx = await subsystem.start();
|
|
47604
|
+
const { pidFile } = getViewerPaths();
|
|
47280
47605
|
cliOutput(
|
|
47281
47606
|
{
|
|
47282
47607
|
running: true,
|
|
47283
|
-
pid:
|
|
47284
|
-
port:
|
|
47285
|
-
host:
|
|
47286
|
-
url: `http://${
|
|
47287
|
-
pidFile
|
|
47608
|
+
pid: ctx.pid,
|
|
47609
|
+
port: ctx.port,
|
|
47610
|
+
host: ctx.host,
|
|
47611
|
+
url: `http://${ctx.host}:${ctx.port}`,
|
|
47612
|
+
pidFile
|
|
47288
47613
|
},
|
|
47289
47614
|
{
|
|
47290
47615
|
command: "docs serve",
|
|
47291
47616
|
operation: "docs.serve",
|
|
47292
|
-
message: `viewer started on http://${
|
|
47617
|
+
message: `viewer started on http://${ctx.host}:${ctx.port}`
|
|
47293
47618
|
}
|
|
47294
47619
|
);
|
|
47295
|
-
return;
|
|
47296
|
-
}
|
|
47297
|
-
let handle;
|
|
47298
|
-
try {
|
|
47299
|
-
handle = await startViewer({
|
|
47300
|
-
startPort,
|
|
47301
|
-
endPort,
|
|
47302
|
-
host,
|
|
47303
|
-
autoIncrement: !noAutoPort
|
|
47304
|
-
});
|
|
47305
47620
|
} catch (err) {
|
|
47306
47621
|
const e = err;
|
|
47307
47622
|
if (e.code === "E_NO_PORT" || e.code === "EADDRINUSE") {
|
|
@@ -47312,49 +47627,12 @@ var init_docs_viewer = __esm({
|
|
|
47312
47627
|
}
|
|
47313
47628
|
throw err;
|
|
47314
47629
|
}
|
|
47315
|
-
const record = {
|
|
47316
|
-
pid: process.pid,
|
|
47317
|
-
port: handle.port,
|
|
47318
|
-
host: handle.host,
|
|
47319
|
-
projectRoot: getProjectRoot37(),
|
|
47320
|
-
startedAt: Date.now()
|
|
47321
|
-
};
|
|
47322
|
-
await writeViewerPidFile(record);
|
|
47323
|
-
const url = `http://${handle.host}:${handle.port}`;
|
|
47324
|
-
if (isDetachedChild) {
|
|
47325
|
-
} else {
|
|
47326
|
-
humanInfo(`viewer listening on ${url} (Ctrl+C to stop)`);
|
|
47327
|
-
cliOutput(
|
|
47328
|
-
{
|
|
47329
|
-
running: true,
|
|
47330
|
-
pid: record.pid,
|
|
47331
|
-
port: record.port,
|
|
47332
|
-
host: record.host,
|
|
47333
|
-
url,
|
|
47334
|
-
pidFile: viewerPidFilePath()
|
|
47335
|
-
},
|
|
47336
|
-
{
|
|
47337
|
-
command: "docs serve",
|
|
47338
|
-
operation: "docs.serve",
|
|
47339
|
-
message: `viewer running on ${url}`
|
|
47340
|
-
}
|
|
47341
|
-
);
|
|
47342
|
-
}
|
|
47343
|
-
const shutdown = async (signal) => {
|
|
47344
|
-
handle.server.close();
|
|
47345
|
-
await removeViewerPidFile();
|
|
47346
|
-
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
47347
|
-
};
|
|
47348
|
-
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
47349
|
-
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
47350
|
-
await new Promise((res) => handle.server.on("close", res));
|
|
47351
|
-
await removeViewerPidFile();
|
|
47352
47630
|
}
|
|
47353
47631
|
});
|
|
47354
47632
|
openCommand = defineCommand({
|
|
47355
47633
|
meta: {
|
|
47356
47634
|
name: "open",
|
|
47357
|
-
description: "
|
|
47635
|
+
description: "Open docs viewer in browser \u2014 prefer `cleo docs viewer open`"
|
|
47358
47636
|
},
|
|
47359
47637
|
args: {
|
|
47360
47638
|
slug: {
|
|
@@ -47365,17 +47643,17 @@ var init_docs_viewer = __esm({
|
|
|
47365
47643
|
port: {
|
|
47366
47644
|
type: "string",
|
|
47367
47645
|
description: "Starting port for the viewer (default 7777)",
|
|
47368
|
-
default:
|
|
47646
|
+
default: String(VIEWER_DEFAULT_PORT)
|
|
47369
47647
|
},
|
|
47370
47648
|
"end-port": {
|
|
47371
47649
|
type: "string",
|
|
47372
47650
|
description: "Last port to try (default 7800)",
|
|
47373
|
-
default:
|
|
47651
|
+
default: String(VIEWER_DEFAULT_END_PORT)
|
|
47374
47652
|
},
|
|
47375
47653
|
host: {
|
|
47376
47654
|
type: "string",
|
|
47377
47655
|
description: "Bind host (default 127.0.0.1)",
|
|
47378
|
-
default:
|
|
47656
|
+
default: VIEWER_DEFAULT_HOST
|
|
47379
47657
|
},
|
|
47380
47658
|
"no-launch": {
|
|
47381
47659
|
type: "boolean",
|
|
@@ -47385,49 +47663,30 @@ var init_docs_viewer = __esm({
|
|
|
47385
47663
|
},
|
|
47386
47664
|
async run({ args }) {
|
|
47387
47665
|
const slug = args.slug ? String(args.slug) : void 0;
|
|
47388
|
-
let
|
|
47389
|
-
if (
|
|
47390
|
-
await removeViewerPidFile();
|
|
47391
|
-
record = null;
|
|
47392
|
-
}
|
|
47393
|
-
if (!record) {
|
|
47666
|
+
let status = await getViewerStatus();
|
|
47667
|
+
if (!status.running) {
|
|
47394
47668
|
const startPort = Number.parseInt(String(args.port), 10);
|
|
47395
47669
|
const endPort = Number.parseInt(String(args["end-port"]), 10);
|
|
47396
47670
|
const host = String(args.host);
|
|
47397
|
-
|
|
47398
|
-
startPort,
|
|
47399
|
-
|
|
47400
|
-
|
|
47401
|
-
|
|
47402
|
-
|
|
47403
|
-
|
|
47404
|
-
|
|
47405
|
-
name: "E_SPAWN_FAILED"
|
|
47406
|
-
});
|
|
47407
|
-
return;
|
|
47408
|
-
}
|
|
47409
|
-
const deadline = Date.now() + 1e4;
|
|
47410
|
-
while (Date.now() < deadline) {
|
|
47411
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
47412
|
-
record = await readViewerPidFile();
|
|
47413
|
-
if (record && record.pid === child.pid) break;
|
|
47414
|
-
if (!isProcessAlive(child.pid)) {
|
|
47415
|
-
cliError(
|
|
47416
|
-
"detached viewer exited before binding (check ~/.local/share/cleo/viewer.log)",
|
|
47417
|
-
1 /* GENERAL_ERROR */,
|
|
47418
|
-
{ name: "E_VIEWER_EXITED" }
|
|
47419
|
-
);
|
|
47420
|
-
return;
|
|
47421
|
-
}
|
|
47422
|
-
}
|
|
47423
|
-
if (!record) {
|
|
47424
|
-
cliError("timed out waiting for viewer to bind", 1 /* GENERAL_ERROR */, {
|
|
47425
|
-
name: "E_VIEWER_TIMEOUT"
|
|
47671
|
+
try {
|
|
47672
|
+
const subsystem = createDocsViewerSubsystem({ startPort, endPort, host });
|
|
47673
|
+
await subsystem.start();
|
|
47674
|
+
status = await getViewerStatus();
|
|
47675
|
+
} catch (err) {
|
|
47676
|
+
const e = err;
|
|
47677
|
+
cliError(e.message ?? "failed to start docs viewer", 1 /* GENERAL_ERROR */, {
|
|
47678
|
+
name: "E_VIEWER_START_FAILED"
|
|
47426
47679
|
});
|
|
47427
47680
|
return;
|
|
47428
47681
|
}
|
|
47429
47682
|
}
|
|
47430
|
-
|
|
47683
|
+
if (!status.running || status.pid === null || status.port === null || status.host === null) {
|
|
47684
|
+
cliError("timed out waiting for viewer to bind", 1 /* GENERAL_ERROR */, {
|
|
47685
|
+
name: "E_VIEWER_TIMEOUT"
|
|
47686
|
+
});
|
|
47687
|
+
return;
|
|
47688
|
+
}
|
|
47689
|
+
const url = slug ? `http://${status.host}:${status.port}/docs/${encodeURIComponent(slug)}` : `http://${status.host}:${status.port}/`;
|
|
47431
47690
|
if (!args["no-launch"]) {
|
|
47432
47691
|
openInBrowser(url);
|
|
47433
47692
|
}
|
|
@@ -47435,9 +47694,9 @@ var init_docs_viewer = __esm({
|
|
|
47435
47694
|
{
|
|
47436
47695
|
opened: true,
|
|
47437
47696
|
slug: slug ?? null,
|
|
47438
|
-
pid:
|
|
47439
|
-
port:
|
|
47440
|
-
host:
|
|
47697
|
+
pid: status.pid,
|
|
47698
|
+
port: status.port,
|
|
47699
|
+
host: status.host,
|
|
47441
47700
|
url
|
|
47442
47701
|
},
|
|
47443
47702
|
{
|
|
@@ -47451,7 +47710,7 @@ var init_docs_viewer = __esm({
|
|
|
47451
47710
|
stopCommand4 = defineCommand({
|
|
47452
47711
|
meta: {
|
|
47453
47712
|
name: "stop",
|
|
47454
|
-
description: "
|
|
47713
|
+
description: "Stop the docs viewer \u2014 prefer `cleo docs viewer stop`"
|
|
47455
47714
|
},
|
|
47456
47715
|
args: {
|
|
47457
47716
|
timeout: {
|
|
@@ -47485,38 +47744,29 @@ var init_docs_viewer = __esm({
|
|
|
47485
47744
|
);
|
|
47486
47745
|
return;
|
|
47487
47746
|
}
|
|
47488
|
-
|
|
47489
|
-
|
|
47490
|
-
|
|
47491
|
-
|
|
47492
|
-
|
|
47493
|
-
|
|
47494
|
-
|
|
47495
|
-
|
|
47496
|
-
|
|
47497
|
-
|
|
47498
|
-
|
|
47499
|
-
}
|
|
47500
|
-
}
|
|
47747
|
+
const { pidFile } = getViewerPaths();
|
|
47748
|
+
const subsystem = createDocsViewerSubsystem({
|
|
47749
|
+
startPort: record.port,
|
|
47750
|
+
host: record.host
|
|
47751
|
+
});
|
|
47752
|
+
await subsystem.shutdown({
|
|
47753
|
+
pid: record.pid,
|
|
47754
|
+
pidFile,
|
|
47755
|
+
port: record.port,
|
|
47756
|
+
host: record.host
|
|
47757
|
+
});
|
|
47501
47758
|
const timeoutSec = Math.max(1, Number.parseInt(String(args.timeout), 10) || 10);
|
|
47502
|
-
const exited = await waitForExit(record.pid, timeoutSec * 1e3);
|
|
47503
|
-
if (!exited) {
|
|
47504
|
-
try {
|
|
47505
|
-
process.kill(record.pid, "SIGKILL");
|
|
47506
|
-
} catch {
|
|
47507
|
-
}
|
|
47508
|
-
}
|
|
47509
|
-
await removeViewerPidFile();
|
|
47510
47759
|
cliOutput(
|
|
47511
47760
|
{
|
|
47512
47761
|
stopped: true,
|
|
47513
47762
|
pid: record.pid,
|
|
47514
|
-
graceful:
|
|
47763
|
+
graceful: true,
|
|
47764
|
+
timeoutSec
|
|
47515
47765
|
},
|
|
47516
47766
|
{
|
|
47517
47767
|
command: "docs stop",
|
|
47518
47768
|
operation: "docs.stop",
|
|
47519
|
-
message:
|
|
47769
|
+
message: `viewer (pid ${record.pid}) stopped`
|
|
47520
47770
|
}
|
|
47521
47771
|
);
|
|
47522
47772
|
}
|
|
@@ -47524,15 +47774,15 @@ var init_docs_viewer = __esm({
|
|
|
47524
47774
|
viewerStatusCommand = defineCommand({
|
|
47525
47775
|
meta: {
|
|
47526
47776
|
name: "viewer-status",
|
|
47527
|
-
description: "
|
|
47777
|
+
description: "Report viewer state \u2014 prefer `cleo docs viewer status`"
|
|
47528
47778
|
},
|
|
47529
47779
|
async run() {
|
|
47530
47780
|
await runViewerStatus();
|
|
47531
47781
|
}
|
|
47532
47782
|
});
|
|
47533
47783
|
runViewerStatus = async () => {
|
|
47534
|
-
const
|
|
47535
|
-
if (!
|
|
47784
|
+
const status = await getViewerStatus();
|
|
47785
|
+
if (!status.running || status.pid === null) {
|
|
47536
47786
|
cliOutput(
|
|
47537
47787
|
{ running: false, pidFile: viewerPidFilePath() },
|
|
47538
47788
|
{
|
|
@@ -47543,40 +47793,19 @@ var init_docs_viewer = __esm({
|
|
|
47543
47793
|
);
|
|
47544
47794
|
return;
|
|
47545
47795
|
}
|
|
47546
|
-
const alive = isProcessAlive(record.pid);
|
|
47547
|
-
if (!alive) {
|
|
47548
|
-
await removeViewerPidFile();
|
|
47549
|
-
cliOutput(
|
|
47550
|
-
{
|
|
47551
|
-
running: false,
|
|
47552
|
-
reason: "stale pidfile",
|
|
47553
|
-
pid: record.pid,
|
|
47554
|
-
pidFile: viewerPidFilePath()
|
|
47555
|
-
},
|
|
47556
|
-
{
|
|
47557
|
-
command: "docs viewer-status",
|
|
47558
|
-
operation: "docs.viewer-status",
|
|
47559
|
-
message: `stale pidfile removed (pid ${record.pid} not alive)`
|
|
47560
|
-
}
|
|
47561
|
-
);
|
|
47562
|
-
return;
|
|
47563
|
-
}
|
|
47564
47796
|
cliOutput(
|
|
47565
47797
|
{
|
|
47566
47798
|
running: true,
|
|
47567
|
-
pid:
|
|
47568
|
-
port:
|
|
47569
|
-
host:
|
|
47570
|
-
|
|
47571
|
-
startedAt: record.startedAt,
|
|
47572
|
-
uptimeMs: Date.now() - record.startedAt,
|
|
47573
|
-
url: `http://${record.host}:${record.port}`,
|
|
47799
|
+
pid: status.pid,
|
|
47800
|
+
port: status.port,
|
|
47801
|
+
host: status.host,
|
|
47802
|
+
url: status.url,
|
|
47574
47803
|
pidFile: viewerPidFilePath()
|
|
47575
47804
|
},
|
|
47576
47805
|
{
|
|
47577
47806
|
command: "docs viewer-status",
|
|
47578
47807
|
operation: "docs.viewer-status",
|
|
47579
|
-
message: `viewer running (pid ${
|
|
47808
|
+
message: `viewer running (pid ${status.pid})`
|
|
47580
47809
|
}
|
|
47581
47810
|
);
|
|
47582
47811
|
};
|
|
@@ -47613,7 +47842,7 @@ __export(docs_exports, {
|
|
|
47613
47842
|
_llmOutputCommand: () => _llmOutputCommand,
|
|
47614
47843
|
docsCommand: () => docsCommand
|
|
47615
47844
|
});
|
|
47616
|
-
import { appendFile, mkdir as
|
|
47845
|
+
import { appendFile, mkdir as mkdir3, readdir, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
|
|
47617
47846
|
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
|
|
47618
47847
|
import { pushWarning as pushWarning3 } from "@cleocode/core";
|
|
47619
47848
|
import {
|
|
@@ -47955,7 +48184,7 @@ var init_docs3 = __esm({
|
|
|
47955
48184
|
})}
|
|
47956
48185
|
`;
|
|
47957
48186
|
try {
|
|
47958
|
-
await
|
|
48187
|
+
await mkdir3(join21(projectRoot, ".cleo", "audit"), { recursive: true });
|
|
47959
48188
|
await appendFile(
|
|
47960
48189
|
join21(projectRoot, ".cleo", "audit", "similar-bypass.jsonl"),
|
|
47961
48190
|
auditLine,
|
|
@@ -48287,7 +48516,7 @@ var init_docs3 = __esm({
|
|
|
48287
48516
|
let writtenPath;
|
|
48288
48517
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48289
48518
|
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48290
|
-
await
|
|
48519
|
+
await mkdir3(dirname8(outPath), { recursive: true });
|
|
48291
48520
|
await writeFile2(outPath, result.content, "utf8");
|
|
48292
48521
|
writtenPath = outPath;
|
|
48293
48522
|
}
|
|
@@ -48359,7 +48588,7 @@ var init_docs3 = __esm({
|
|
|
48359
48588
|
let writtenPath;
|
|
48360
48589
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48361
48590
|
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48362
|
-
await
|
|
48591
|
+
await mkdir3(dirname8(outPath), { recursive: true });
|
|
48363
48592
|
await writeFile2(outPath, result.content, "utf8");
|
|
48364
48593
|
writtenPath = outPath;
|
|
48365
48594
|
}
|
|
@@ -48436,7 +48665,7 @@ var init_docs3 = __esm({
|
|
|
48436
48665
|
let writtenPath;
|
|
48437
48666
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48438
48667
|
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48439
|
-
await
|
|
48668
|
+
await mkdir3(dirname8(outPath), { recursive: true });
|
|
48440
48669
|
await writeFile2(outPath, result.content, "utf8");
|
|
48441
48670
|
writtenPath = outPath;
|
|
48442
48671
|
}
|
|
@@ -48662,7 +48891,7 @@ var init_docs3 = __esm({
|
|
|
48662
48891
|
});
|
|
48663
48892
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48664
48893
|
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48665
|
-
await
|
|
48894
|
+
await mkdir3(dirname8(outPath), { recursive: true });
|
|
48666
48895
|
await writeFile2(outPath, result.merged, "utf8");
|
|
48667
48896
|
humanInfo(`Wrote merged content to ${outPath}`);
|
|
48668
48897
|
}
|
|
@@ -49434,7 +49663,7 @@ var init_docs3 = __esm({
|
|
|
49434
49663
|
})}
|
|
49435
49664
|
`;
|
|
49436
49665
|
try {
|
|
49437
|
-
await
|
|
49666
|
+
await mkdir3(join21(projectRoot, ".cleo", "audit"), { recursive: true });
|
|
49438
49667
|
await appendFile(
|
|
49439
49668
|
join21(projectRoot, ".cleo", "audit", "import-force-bypass.jsonl"),
|
|
49440
49669
|
auditLine,
|
|
@@ -50899,9 +51128,18 @@ var init_doctor = __esm({
|
|
|
50899
51128
|
type: "boolean",
|
|
50900
51129
|
description: "Migrate <root>/.cleo/worktree-include (legacy) \u2192 <root>/.worktreeinclude (canonical, T9983). Combine with --dry-run to preview."
|
|
50901
51130
|
},
|
|
51131
|
+
/**
|
|
51132
|
+
* T11489 — DHQ-037/019: detect and auto-heal a leaked `core.worktree` key
|
|
51133
|
+
* in the shared `.git/config`. Reports E_WT_CONFIG_LEAK when found; heals
|
|
51134
|
+
* automatically unless `--dry-run` is passed.
|
|
51135
|
+
*/
|
|
51136
|
+
"check-worktree-config": {
|
|
51137
|
+
type: "boolean",
|
|
51138
|
+
description: "Detect and auto-heal a leaked core.worktree key in .git/config (T11489 / DHQ-037). Combine with --dry-run to report without healing."
|
|
51139
|
+
},
|
|
50902
51140
|
"dry-run": {
|
|
50903
51141
|
type: "boolean",
|
|
50904
|
-
description: "With --quarantine-rogue-cleo-dirs
|
|
51142
|
+
description: "With --quarantine-rogue-cleo-dirs, --scan-stray-nexus-dbs, or --check-worktree-config: print what would be done without acting"
|
|
50905
51143
|
},
|
|
50906
51144
|
/**
|
|
50907
51145
|
* Show brain.db health dashboard (T1908 / BBTT-W2-4).
|
|
@@ -50951,6 +51189,61 @@ var init_doctor = __esm({
|
|
|
50951
51189
|
const progress = createDoctorProgress(isHuman);
|
|
50952
51190
|
progress.start();
|
|
50953
51191
|
try {
|
|
51192
|
+
if (args["check-worktree-config"]) {
|
|
51193
|
+
const { execFileSync: execFile2 } = await import("node:child_process");
|
|
51194
|
+
const { join: pathJoin } = await import("node:path");
|
|
51195
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
51196
|
+
const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
|
|
51197
|
+
const projectRoot = getProjectRoot42();
|
|
51198
|
+
let gitRoot = projectRoot;
|
|
51199
|
+
try {
|
|
51200
|
+
gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
|
|
51201
|
+
cwd: projectRoot,
|
|
51202
|
+
encoding: "utf-8",
|
|
51203
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
51204
|
+
}).trim();
|
|
51205
|
+
} catch {
|
|
51206
|
+
}
|
|
51207
|
+
const isDryRun = args["dry-run"] === true;
|
|
51208
|
+
progress.step(0, "Checking for leaked core.worktree in .git/config");
|
|
51209
|
+
if (isDryRun) {
|
|
51210
|
+
const gitConfigPath = pathJoin(gitRoot, ".git", "config");
|
|
51211
|
+
let leakedValue;
|
|
51212
|
+
if (existsSync21(gitConfigPath)) {
|
|
51213
|
+
try {
|
|
51214
|
+
leakedValue = execFile2("git", ["config", "--file", gitConfigPath, "--get", "core.worktree"], {
|
|
51215
|
+
encoding: "utf-8",
|
|
51216
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
51217
|
+
}).trim() || void 0;
|
|
51218
|
+
} catch {
|
|
51219
|
+
}
|
|
51220
|
+
}
|
|
51221
|
+
const report = {
|
|
51222
|
+
gitRoot,
|
|
51223
|
+
gitConfigPath,
|
|
51224
|
+
leakDetected: !!leakedValue,
|
|
51225
|
+
leakedValue,
|
|
51226
|
+
healed: false,
|
|
51227
|
+
dryRun: true,
|
|
51228
|
+
message: leakedValue ? `DRY-RUN: core.worktree="${leakedValue}" found \u2014 would unset` : "No core.worktree leak detected"
|
|
51229
|
+
};
|
|
51230
|
+
progress.complete(report.message);
|
|
51231
|
+
cliOutput(report, { command: "doctor", operation: "doctor.check-worktree-config" });
|
|
51232
|
+
if (leakedValue) process.exitCode = 2;
|
|
51233
|
+
} else {
|
|
51234
|
+
const result = detectAndHealCoreWorktreeLeak(gitRoot);
|
|
51235
|
+
const report = {
|
|
51236
|
+
gitRoot,
|
|
51237
|
+
...result,
|
|
51238
|
+
dryRun: false,
|
|
51239
|
+
message: result.leakDetected ? result.healed ? `E_WT_CONFIG_LEAK healed: removed core.worktree="${result.leakedValue}"` : `E_WT_CONFIG_LEAK detected but heal FAILED: ${result.healError}` : "No core.worktree leak detected"
|
|
51240
|
+
};
|
|
51241
|
+
progress.complete(report.message);
|
|
51242
|
+
cliOutput(report, { command: "doctor", operation: "doctor.check-worktree-config" });
|
|
51243
|
+
if (result.leakDetected && !result.healed) process.exitCode = 1;
|
|
51244
|
+
}
|
|
51245
|
+
return;
|
|
51246
|
+
}
|
|
50954
51247
|
if (args.brain) {
|
|
50955
51248
|
const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
|
|
50956
51249
|
const projectRoot = getProjectRoot42();
|
|
@@ -52522,12 +52815,54 @@ var init_gc = __esm({
|
|
|
52522
52815
|
}
|
|
52523
52816
|
});
|
|
52524
52817
|
|
|
52818
|
+
// packages/cleo/src/cli/commands/go.ts
|
|
52819
|
+
var go_exports = {};
|
|
52820
|
+
__export(go_exports, {
|
|
52821
|
+
goCommand: () => goCommand
|
|
52822
|
+
});
|
|
52823
|
+
import { getProjectRoot as getProjectRoot43, go } from "@cleocode/core";
|
|
52824
|
+
var goCommand;
|
|
52825
|
+
var init_go = __esm({
|
|
52826
|
+
"packages/cleo/src/cli/commands/go.ts"() {
|
|
52827
|
+
"use strict";
|
|
52828
|
+
init_define_cli_command();
|
|
52829
|
+
init_renderers();
|
|
52830
|
+
goCommand = defineCommand({
|
|
52831
|
+
meta: {
|
|
52832
|
+
name: "go",
|
|
52833
|
+
description: "SG-AUTOPILOT: run one turn of briefing\u2192sagaNext\u2192ready\u2192stage-branch\u2192ivtr loop"
|
|
52834
|
+
},
|
|
52835
|
+
args: {
|
|
52836
|
+
saga: {
|
|
52837
|
+
type: "string",
|
|
52838
|
+
description: "Optional saga task ID to scope the autopilot run (default: auto-select)",
|
|
52839
|
+
required: false
|
|
52840
|
+
},
|
|
52841
|
+
headless: {
|
|
52842
|
+
type: "boolean",
|
|
52843
|
+
description: "Suppress interactive annotations; suitable for daemon / unattended use",
|
|
52844
|
+
required: false
|
|
52845
|
+
}
|
|
52846
|
+
},
|
|
52847
|
+
async run({ args }) {
|
|
52848
|
+
const projectRoot = getProjectRoot43();
|
|
52849
|
+
const result = await go.cleoGo({
|
|
52850
|
+
sagaId: typeof args.saga === "string" && args.saga.length > 0 ? args.saga : void 0,
|
|
52851
|
+
headless: args.headless === true,
|
|
52852
|
+
projectRoot
|
|
52853
|
+
});
|
|
52854
|
+
cliOutput(result.success ? result.data : result, { command: "go", operation: "go.run" });
|
|
52855
|
+
}
|
|
52856
|
+
});
|
|
52857
|
+
}
|
|
52858
|
+
});
|
|
52859
|
+
|
|
52525
52860
|
// packages/cleo/src/cli/commands/goal.ts
|
|
52526
52861
|
var goal_exports = {};
|
|
52527
52862
|
__export(goal_exports, {
|
|
52528
52863
|
goalCommand: () => goalCommand
|
|
52529
52864
|
});
|
|
52530
|
-
import { getProjectRoot as
|
|
52865
|
+
import { getProjectRoot as getProjectRoot44, goal } from "@cleocode/core";
|
|
52531
52866
|
function resolveGoalKind(task) {
|
|
52532
52867
|
if (typeof task === "string" && task.length > 0) {
|
|
52533
52868
|
if (!isValidGoalTargetTaskId(task)) {
|
|
@@ -52541,7 +52876,7 @@ function resolveTurnBudget(turns) {
|
|
|
52541
52876
|
const n = typeof turns === "string" ? Number.parseInt(turns, 10) : Number(turns);
|
|
52542
52877
|
return Number.isInteger(n) && n > 0 ? n : DEFAULT_TURN_BUDGET;
|
|
52543
52878
|
}
|
|
52544
|
-
var DEFAULT_TURN_BUDGET, setCommand, statusCommand9, subgoalCommand, appendCommand, goalCommand;
|
|
52879
|
+
var DEFAULT_TURN_BUDGET, setCommand, statusCommand9, subgoalCommand, advanceCommand2, appendCommand, goalCommand;
|
|
52545
52880
|
var init_goal2 = __esm({
|
|
52546
52881
|
"packages/cleo/src/cli/commands/goal.ts"() {
|
|
52547
52882
|
"use strict";
|
|
@@ -52574,7 +52909,7 @@ var init_goal2 = __esm({
|
|
|
52574
52909
|
}
|
|
52575
52910
|
const record = await goal.createGoal(
|
|
52576
52911
|
{ goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
|
|
52577
|
-
|
|
52912
|
+
getProjectRoot44()
|
|
52578
52913
|
);
|
|
52579
52914
|
cliOutput(record, { command: "goal set", operation: "goal.set" });
|
|
52580
52915
|
}
|
|
@@ -52585,7 +52920,7 @@ var init_goal2 = __esm({
|
|
|
52585
52920
|
description: "Show the current agent's active goal (per-agent scoped)."
|
|
52586
52921
|
},
|
|
52587
52922
|
async run() {
|
|
52588
|
-
const record = await goal.getActiveGoal(
|
|
52923
|
+
const record = await goal.getActiveGoal(getProjectRoot44());
|
|
52589
52924
|
cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
|
|
52590
52925
|
}
|
|
52591
52926
|
});
|
|
@@ -52607,7 +52942,7 @@ var init_goal2 = __esm({
|
|
|
52607
52942
|
});
|
|
52608
52943
|
return;
|
|
52609
52944
|
}
|
|
52610
|
-
const cwd =
|
|
52945
|
+
const cwd = getProjectRoot44();
|
|
52611
52946
|
const parent = await goal.getActiveGoal(cwd);
|
|
52612
52947
|
if (!parent) {
|
|
52613
52948
|
cliError(
|
|
@@ -52636,6 +52971,34 @@ var init_goal2 = __esm({
|
|
|
52636
52971
|
cliOutput(record, { command: "goal subgoal", operation: "goal.subgoal" });
|
|
52637
52972
|
}
|
|
52638
52973
|
});
|
|
52974
|
+
advanceCommand2 = defineCommand({
|
|
52975
|
+
meta: {
|
|
52976
|
+
name: "advance",
|
|
52977
|
+
description: "Advance a goal one turn (load \u2192 judge \u2192 persist \u2192 continuation). Entry point for the Stop-hook loop."
|
|
52978
|
+
},
|
|
52979
|
+
args: {
|
|
52980
|
+
goalId: {
|
|
52981
|
+
type: "positional",
|
|
52982
|
+
description: "The goal id (idempotency key) to advance"
|
|
52983
|
+
}
|
|
52984
|
+
},
|
|
52985
|
+
async run({ args }) {
|
|
52986
|
+
const goalId = String(args.goalId ?? "").trim();
|
|
52987
|
+
if (goalId.length === 0) {
|
|
52988
|
+
cliError("goal advance requires a <goalId>", 6 /* VALIDATION_ERROR */, {
|
|
52989
|
+
name: "E_VALIDATION"
|
|
52990
|
+
});
|
|
52991
|
+
return;
|
|
52992
|
+
}
|
|
52993
|
+
const cwd = getProjectRoot44();
|
|
52994
|
+
const result = await goal.advanceGoalWithPersist(goalId, { cwd });
|
|
52995
|
+
if (!result) {
|
|
52996
|
+
cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
|
|
52997
|
+
return;
|
|
52998
|
+
}
|
|
52999
|
+
cliOutput(result, { command: "goal advance", operation: "goal.advance" });
|
|
53000
|
+
}
|
|
53001
|
+
});
|
|
52639
53002
|
appendCommand = defineCommand({
|
|
52640
53003
|
meta: {
|
|
52641
53004
|
name: "append",
|
|
@@ -52652,7 +53015,7 @@ var init_goal2 = __esm({
|
|
|
52652
53015
|
});
|
|
52653
53016
|
return;
|
|
52654
53017
|
}
|
|
52655
|
-
const cwd =
|
|
53018
|
+
const cwd = getProjectRoot44();
|
|
52656
53019
|
const active = await goal.getActiveGoal(cwd);
|
|
52657
53020
|
if (!active) {
|
|
52658
53021
|
cliError(
|
|
@@ -52671,11 +53034,12 @@ var init_goal2 = __esm({
|
|
|
52671
53034
|
goalCommand = defineCommand({
|
|
52672
53035
|
meta: {
|
|
52673
53036
|
name: "goal",
|
|
52674
|
-
description: "DB-persisted, per-agent, evidence-gate-aware goal loop (set/status/subgoal/append)."
|
|
53037
|
+
description: "DB-persisted, per-agent, evidence-gate-aware goal loop (set/status/advance/subgoal/append)."
|
|
52675
53038
|
},
|
|
52676
53039
|
subCommands: {
|
|
52677
53040
|
set: setCommand,
|
|
52678
53041
|
status: statusCommand9,
|
|
53042
|
+
advance: advanceCommand2,
|
|
52679
53043
|
subgoal: subgoalCommand,
|
|
52680
53044
|
append: appendCommand
|
|
52681
53045
|
},
|
|
@@ -53640,7 +54004,7 @@ var hygiene_exports = {};
|
|
|
53640
54004
|
__export(hygiene_exports, {
|
|
53641
54005
|
hygieneCommand: () => hygieneCommand
|
|
53642
54006
|
});
|
|
53643
|
-
import { getProjectRoot as
|
|
54007
|
+
import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
|
|
53644
54008
|
import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
|
|
53645
54009
|
var hygieneCommand;
|
|
53646
54010
|
var init_hygiene = __esm({
|
|
@@ -53669,7 +54033,7 @@ var init_hygiene = __esm({
|
|
|
53669
54033
|
}
|
|
53670
54034
|
},
|
|
53671
54035
|
async run({ args }) {
|
|
53672
|
-
const projectRoot = args["project-root"] ||
|
|
54036
|
+
const projectRoot = args["project-root"] || getProjectRoot45() || process.cwd();
|
|
53673
54037
|
const worktreePath = args["worktree-path"];
|
|
53674
54038
|
await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
|
|
53675
54039
|
}
|
|
@@ -53842,7 +54206,7 @@ __export(init_exports, {
|
|
|
53842
54206
|
});
|
|
53843
54207
|
import { existsSync as existsSync15, readFileSync as readFileSync14 } from "node:fs";
|
|
53844
54208
|
import { join as join27 } from "node:path";
|
|
53845
|
-
import { fileURLToPath as
|
|
54209
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
53846
54210
|
import {
|
|
53847
54211
|
CleoError as CleoError5,
|
|
53848
54212
|
getWorkflowTemplatesDir as getCoreWorkflowTemplatesDir,
|
|
@@ -53853,7 +54217,7 @@ import {
|
|
|
53853
54217
|
import { getTemplatesByKind } from "@cleocode/core/templates/registry";
|
|
53854
54218
|
function getGitignoreTemplate() {
|
|
53855
54219
|
try {
|
|
53856
|
-
const thisFile =
|
|
54220
|
+
const thisFile = fileURLToPath5(import.meta.url);
|
|
53857
54221
|
const packageRoot = join27(thisFile, "..", "..", "..", "..");
|
|
53858
54222
|
const localTemplatePath = join27(packageRoot, "templates", "cleo-gitignore");
|
|
53859
54223
|
const monorepoTemplatePath = join27(packageRoot, "..", "..", "templates", "cleo-gitignore");
|
|
@@ -54831,7 +55195,7 @@ var llm_cost_exports = {};
|
|
|
54831
55195
|
__export(llm_cost_exports, {
|
|
54832
55196
|
costCommand: () => costCommand
|
|
54833
55197
|
});
|
|
54834
|
-
import { getProjectRoot as
|
|
55198
|
+
import { getProjectRoot as getProjectRoot46 } from "@cleocode/core/internal";
|
|
54835
55199
|
import { computeCost } from "@cleocode/core/llm/usage-pricing";
|
|
54836
55200
|
function resolveSessionId(raw) {
|
|
54837
55201
|
if (raw === "current") {
|
|
@@ -54904,7 +55268,7 @@ var init_llm_cost = __esm({
|
|
|
54904
55268
|
process.exit(6);
|
|
54905
55269
|
}
|
|
54906
55270
|
const sessionId = resolveSessionId(rawSessionId);
|
|
54907
|
-
const projectRoot =
|
|
55271
|
+
const projectRoot = getProjectRoot46(process.cwd());
|
|
54908
55272
|
let breakdown;
|
|
54909
55273
|
try {
|
|
54910
55274
|
breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
|
|
@@ -56451,7 +56815,7 @@ var memory_exports = {};
|
|
|
56451
56815
|
__export(memory_exports, {
|
|
56452
56816
|
memoryCommand: () => memoryCommand
|
|
56453
56817
|
});
|
|
56454
|
-
import { getProjectRoot as
|
|
56818
|
+
import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
|
|
56455
56819
|
import {
|
|
56456
56820
|
getBrainDb as getBrainDb2,
|
|
56457
56821
|
getDreamStatus,
|
|
@@ -57384,7 +57748,7 @@ var init_memory3 = __esm({
|
|
|
57384
57748
|
},
|
|
57385
57749
|
args: {},
|
|
57386
57750
|
async run() {
|
|
57387
|
-
const root =
|
|
57751
|
+
const root = getProjectRoot47();
|
|
57388
57752
|
try {
|
|
57389
57753
|
const result = await runConsolidation(root);
|
|
57390
57754
|
cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
|
|
@@ -57408,7 +57772,7 @@ var init_memory3 = __esm({
|
|
|
57408
57772
|
}
|
|
57409
57773
|
},
|
|
57410
57774
|
async run({ args }) {
|
|
57411
|
-
const root =
|
|
57775
|
+
const root = getProjectRoot47();
|
|
57412
57776
|
if (args.status) {
|
|
57413
57777
|
try {
|
|
57414
57778
|
const status = await getDreamStatus(root);
|
|
@@ -57445,7 +57809,7 @@ var init_memory3 = __esm({
|
|
|
57445
57809
|
}
|
|
57446
57810
|
},
|
|
57447
57811
|
async run({ args }) {
|
|
57448
|
-
const root =
|
|
57812
|
+
const root = getProjectRoot47();
|
|
57449
57813
|
try {
|
|
57450
57814
|
const { runObserver, runReflector } = await import("@cleocode/core/memory");
|
|
57451
57815
|
const observerResult = await runObserver(root, args.session, {
|
|
@@ -57485,7 +57849,7 @@ var init_memory3 = __esm({
|
|
|
57485
57849
|
}
|
|
57486
57850
|
},
|
|
57487
57851
|
async run({ args }) {
|
|
57488
|
-
const root =
|
|
57852
|
+
const root = getProjectRoot47();
|
|
57489
57853
|
try {
|
|
57490
57854
|
await getBrainDb2(root);
|
|
57491
57855
|
const { totalDuplicateRows, groups } = await scanDuplicateEntries();
|
|
@@ -57531,7 +57895,7 @@ var init_memory3 = __esm({
|
|
|
57531
57895
|
async run({ args }) {
|
|
57532
57896
|
const sourceDir = args.from;
|
|
57533
57897
|
const isDryRun = !!args["dry-run"];
|
|
57534
|
-
const projectRoot =
|
|
57898
|
+
const projectRoot = getProjectRoot47();
|
|
57535
57899
|
try {
|
|
57536
57900
|
const result = await importMemoryFiles({
|
|
57537
57901
|
sourceDir,
|
|
@@ -57682,7 +58046,7 @@ var init_memory3 = __esm({
|
|
|
57682
58046
|
},
|
|
57683
58047
|
args: {},
|
|
57684
58048
|
async run() {
|
|
57685
|
-
const root =
|
|
58049
|
+
const root = getProjectRoot47();
|
|
57686
58050
|
try {
|
|
57687
58051
|
await getBrainDb2(root);
|
|
57688
58052
|
const result = await getTierStats(root);
|
|
@@ -57725,7 +58089,7 @@ var init_memory3 = __esm({
|
|
|
57725
58089
|
}
|
|
57726
58090
|
},
|
|
57727
58091
|
async run({ args }) {
|
|
57728
|
-
const root =
|
|
58092
|
+
const root = getProjectRoot47();
|
|
57729
58093
|
const targetTier = args.to;
|
|
57730
58094
|
const reason = args.reason;
|
|
57731
58095
|
const validTiers = ["medium", "long"];
|
|
@@ -57791,7 +58155,7 @@ var init_memory3 = __esm({
|
|
|
57791
58155
|
}
|
|
57792
58156
|
},
|
|
57793
58157
|
async run({ args }) {
|
|
57794
|
-
const root =
|
|
58158
|
+
const root = getProjectRoot47();
|
|
57795
58159
|
const targetTier = args.to;
|
|
57796
58160
|
const reason = args.reason;
|
|
57797
58161
|
const validTiers = ["short", "medium"];
|
|
@@ -58254,7 +58618,7 @@ var migrate_claude_mem_exports = {};
|
|
|
58254
58618
|
__export(migrate_claude_mem_exports, {
|
|
58255
58619
|
migrateClaudeMemCommand: () => migrateClaudeMemCommand
|
|
58256
58620
|
});
|
|
58257
|
-
import { getProjectRoot as
|
|
58621
|
+
import { getProjectRoot as getProjectRoot48, migrateClaudeMem } from "@cleocode/core/internal";
|
|
58258
58622
|
import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
|
|
58259
58623
|
import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
|
|
58260
58624
|
var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
|
|
@@ -58317,7 +58681,7 @@ var init_migrate_claude_mem = __esm({
|
|
|
58317
58681
|
}
|
|
58318
58682
|
},
|
|
58319
58683
|
async run({ args }) {
|
|
58320
|
-
const root =
|
|
58684
|
+
const root = getProjectRoot48();
|
|
58321
58685
|
try {
|
|
58322
58686
|
const result = await migrateClaudeMem(root, {
|
|
58323
58687
|
sourcePath: args.source,
|
|
@@ -58366,7 +58730,7 @@ var init_migrate_claude_mem = __esm({
|
|
|
58366
58730
|
}
|
|
58367
58731
|
},
|
|
58368
58732
|
async run({ args }) {
|
|
58369
|
-
const projectRoot =
|
|
58733
|
+
const projectRoot = getProjectRoot48();
|
|
58370
58734
|
try {
|
|
58371
58735
|
const db = await getDb2(projectRoot);
|
|
58372
58736
|
const rcasdFlag = Boolean(args.rcasd);
|
|
@@ -58481,10 +58845,10 @@ var nexus_exports = {};
|
|
|
58481
58845
|
__export(nexus_exports, {
|
|
58482
58846
|
nexusCommand: () => nexusCommand
|
|
58483
58847
|
});
|
|
58484
|
-
import { appendFile as appendFile2, mkdir as
|
|
58848
|
+
import { appendFile as appendFile2, mkdir as mkdir4 } from "node:fs/promises";
|
|
58485
58849
|
import { homedir as homedir5 } from "node:os";
|
|
58486
58850
|
import path4 from "node:path";
|
|
58487
|
-
import { getProjectRoot as
|
|
58851
|
+
import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
|
|
58488
58852
|
import { getSymbolImpact } from "@cleocode/core/nexus";
|
|
58489
58853
|
import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
|
|
58490
58854
|
import { exportNexusGraph } from "@cleocode/core/nexus/export.js";
|
|
@@ -58493,7 +58857,7 @@ async function appendDeprecationTelemetry(op, replacement) {
|
|
|
58493
58857
|
try {
|
|
58494
58858
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
58495
58859
|
const dir = path4.join(homedir5(), ".local", "state", "cleo", "nexus-deprecation");
|
|
58496
|
-
await
|
|
58860
|
+
await mkdir4(dir, { recursive: true });
|
|
58497
58861
|
const record = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), op, replacement }) + "\n";
|
|
58498
58862
|
await appendFile2(path4.join(dir, `${dateStr}.jsonl`), record, "utf8");
|
|
58499
58863
|
} catch {
|
|
@@ -58599,7 +58963,7 @@ var init_nexus3 = __esm({
|
|
|
58599
58963
|
async run({ args }) {
|
|
58600
58964
|
applyJsonFlag2(args.json);
|
|
58601
58965
|
const projectIdOverride = args["project-id"];
|
|
58602
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
58966
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
58603
58967
|
const startTime = Date.now();
|
|
58604
58968
|
try {
|
|
58605
58969
|
const [{ getNexusDb, nexusSchema }, { getIndexStats }] = await Promise.all([
|
|
@@ -59114,7 +59478,7 @@ var init_nexus3 = __esm({
|
|
|
59114
59478
|
applyJsonFlag2(args.json);
|
|
59115
59479
|
const startTime = Date.now();
|
|
59116
59480
|
const projectIdOverride = args["project-id"];
|
|
59117
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
59481
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59118
59482
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
59119
59483
|
const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
|
|
59120
59484
|
const durationMs = Date.now() - startTime;
|
|
@@ -59158,7 +59522,7 @@ var init_nexus3 = __esm({
|
|
|
59158
59522
|
applyJsonFlag2(args.json);
|
|
59159
59523
|
const startTime = Date.now();
|
|
59160
59524
|
const projectIdOverride = args["project-id"];
|
|
59161
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
59525
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59162
59526
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
59163
59527
|
const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
|
|
59164
59528
|
const durationMs = Date.now() - startTime;
|
|
@@ -59201,7 +59565,7 @@ var init_nexus3 = __esm({
|
|
|
59201
59565
|
void appendDeprecationTelemetry("nexus.context", "cleo graph context");
|
|
59202
59566
|
const startTime = Date.now();
|
|
59203
59567
|
const projectIdOverride = args["project-id"];
|
|
59204
|
-
const repoPath =
|
|
59568
|
+
const repoPath = getProjectRoot49();
|
|
59205
59569
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
59206
59570
|
const limit = parseInt(args.limit, 10);
|
|
59207
59571
|
const symbolName = args.symbol;
|
|
@@ -59264,7 +59628,7 @@ var init_nexus3 = __esm({
|
|
|
59264
59628
|
const startTime = Date.now();
|
|
59265
59629
|
const whyFlag = !!args.why;
|
|
59266
59630
|
const projectIdOverride = args["project-id"];
|
|
59267
|
-
const repoPath =
|
|
59631
|
+
const repoPath = getProjectRoot49();
|
|
59268
59632
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
59269
59633
|
const maxDepth = Math.min(parseInt(args.depth, 10), 5);
|
|
59270
59634
|
const symbolName = args.symbol;
|
|
@@ -59336,7 +59700,7 @@ var init_nexus3 = __esm({
|
|
|
59336
59700
|
const projectIdOverride = args["project-id"];
|
|
59337
59701
|
const isIncremental = !!args.incremental;
|
|
59338
59702
|
const ctx = getFormatContext();
|
|
59339
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
59703
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59340
59704
|
humanInfo(`[nexus] Analyzing: ${repoPath}${isIncremental ? " (incremental)" : ""}`);
|
|
59341
59705
|
if (!isIncremental) humanInfo("[nexus] Clearing existing index for project...");
|
|
59342
59706
|
try {
|
|
@@ -59439,7 +59803,7 @@ var init_nexus3 = __esm({
|
|
|
59439
59803
|
async run({ args }) {
|
|
59440
59804
|
applyJsonFlag2(args.json);
|
|
59441
59805
|
const startTime = Date.now();
|
|
59442
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
59806
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59443
59807
|
const name = args.name;
|
|
59444
59808
|
const response = await dispatchRaw("mutate", "nexus", "projects.register", {
|
|
59445
59809
|
path: repoPath,
|
|
@@ -59797,7 +60161,7 @@ var init_nexus3 = __esm({
|
|
|
59797
60161
|
applyJsonFlag2(args.json);
|
|
59798
60162
|
const startTime = Date.now();
|
|
59799
60163
|
const projectIdOverride = args["project-id"];
|
|
59800
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60164
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59801
60165
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
59802
60166
|
const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
|
|
59803
60167
|
repoPath,
|
|
@@ -59903,7 +60267,7 @@ var init_nexus3 = __esm({
|
|
|
59903
60267
|
async run({ args }) {
|
|
59904
60268
|
applyJsonFlag2(args.json);
|
|
59905
60269
|
const startTime = Date.now();
|
|
59906
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60270
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
59907
60271
|
const projectIdOverride = args["project-id"];
|
|
59908
60272
|
const beforeRef = args.before ?? "HEAD~1";
|
|
59909
60273
|
const afterRef = args.after ?? "HEAD";
|
|
@@ -60021,7 +60385,7 @@ var init_nexus3 = __esm({
|
|
|
60021
60385
|
applyJsonFlag2(args.json);
|
|
60022
60386
|
const startTime = Date.now();
|
|
60023
60387
|
const projectIdOverride = args["project-id"];
|
|
60024
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60388
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
60025
60389
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
60026
60390
|
const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
|
|
60027
60391
|
const durationMs = Date.now() - startTime;
|
|
@@ -60077,7 +60441,7 @@ var init_nexus3 = __esm({
|
|
|
60077
60441
|
const startTime = Date.now();
|
|
60078
60442
|
const routeSymbol = args.routeSymbol;
|
|
60079
60443
|
const projectIdOverride = args["project-id"];
|
|
60080
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60444
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
60081
60445
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
60082
60446
|
const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
|
|
60083
60447
|
const durationMs = Date.now() - startTime;
|
|
@@ -60467,7 +60831,7 @@ var init_nexus3 = __esm({
|
|
|
60467
60831
|
async run({ args }) {
|
|
60468
60832
|
applyJsonFlag2(args.json);
|
|
60469
60833
|
const startTime = Date.now();
|
|
60470
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60834
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
60471
60835
|
const projectIdOverride = args["project-id"];
|
|
60472
60836
|
const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
60473
60837
|
const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
|
|
@@ -60571,7 +60935,7 @@ var init_nexus3 = __esm({
|
|
|
60571
60935
|
async run({ args }) {
|
|
60572
60936
|
applyJsonFlag2(args.json);
|
|
60573
60937
|
const startTime = Date.now();
|
|
60574
|
-
const repoPath = args.path ? path4.resolve(args.path) :
|
|
60938
|
+
const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
|
|
60575
60939
|
const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
|
|
60576
60940
|
const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
|
|
60577
60941
|
projectId,
|
|
@@ -60652,7 +61016,7 @@ var init_nexus3 = __esm({
|
|
|
60652
61016
|
const isIncremental = !!args.incremental;
|
|
60653
61017
|
try {
|
|
60654
61018
|
const result = await runNexusWiki({
|
|
60655
|
-
projectRoot:
|
|
61019
|
+
projectRoot: getProjectRoot49(),
|
|
60656
61020
|
outputDir,
|
|
60657
61021
|
communityFilter,
|
|
60658
61022
|
incremental: isIncremental
|
|
@@ -61002,7 +61366,7 @@ __export(orchestrate_exports, {
|
|
|
61002
61366
|
});
|
|
61003
61367
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
61004
61368
|
import { orchestration } from "@cleocode/core";
|
|
61005
|
-
import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as
|
|
61369
|
+
import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot50 } from "@cleocode/core/internal";
|
|
61006
61370
|
function formatRollupTable(rollup) {
|
|
61007
61371
|
const waves = "waves" in rollup ? rollup.waves : [rollup];
|
|
61008
61372
|
const lines = [];
|
|
@@ -61037,7 +61401,7 @@ function formatRollupTable(rollup) {
|
|
|
61037
61401
|
}
|
|
61038
61402
|
return lines.join("\n");
|
|
61039
61403
|
}
|
|
61040
|
-
var rollupCommand, startCommand5, statusCommand12, dashboardCommand, analyzeCommand4, readyCommand, reportCommand, nextCommand2, wavesCommand2, planCommand, spawnCommand2, validateCommand6, contextCommand5, ivtrCommand, parallelCommand, tesseraListCommand, tesseraInstantiateCommand, tesseraCommand, unblockCommand, bootstrapCommand,
|
|
61404
|
+
var rollupCommand, startCommand5, statusCommand12, dashboardCommand, analyzeCommand4, readyCommand, reportCommand, nextCommand2, wavesCommand2, planCommand, spawnCommand2, validateCommand6, contextCommand5, ivtrCommand, parallelCommand, tesseraListCommand, tesseraInstantiateCommand, tesseraCommand, unblockCommand, bootstrapCommand, classifyCommand2, fanoutStatusCommand, handoffCommand, spawnExecuteCommand, fanoutCommand, pruneCommand, worktreeCompleteCommand, conduitStatusCommand, conduitPeekCommand, conduitStartCommand, conduitStopCommand, approveCommand, rejectCommand, pendingCommand, conduitSendCommand, orchestrateCommand;
|
|
61041
61405
|
var init_orchestrate3 = __esm({
|
|
61042
61406
|
"packages/cleo/src/cli/commands/orchestrate.ts"() {
|
|
61043
61407
|
"use strict";
|
|
@@ -61145,7 +61509,7 @@ var init_orchestrate3 = __esm({
|
|
|
61145
61509
|
},
|
|
61146
61510
|
async run({ args }) {
|
|
61147
61511
|
const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
|
|
61148
|
-
const metrics = await orchestration.collectOrchestrateDashboard(
|
|
61512
|
+
const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot50(), {
|
|
61149
61513
|
...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
|
|
61150
61514
|
});
|
|
61151
61515
|
cliOutput(metrics, {
|
|
@@ -61626,7 +61990,7 @@ var init_orchestrate3 = __esm({
|
|
|
61626
61990
|
);
|
|
61627
61991
|
}
|
|
61628
61992
|
});
|
|
61629
|
-
|
|
61993
|
+
classifyCommand2 = defineCommand({
|
|
61630
61994
|
meta: {
|
|
61631
61995
|
name: "classify",
|
|
61632
61996
|
description: "Classify a request using CANT prompt-based team routing"
|
|
@@ -61965,7 +62329,7 @@ var init_orchestrate3 = __esm({
|
|
|
61965
62329
|
tessera: tesseraCommand,
|
|
61966
62330
|
unblock: unblockCommand,
|
|
61967
62331
|
bootstrap: bootstrapCommand,
|
|
61968
|
-
classify:
|
|
62332
|
+
classify: classifyCommand2,
|
|
61969
62333
|
"fanout-status": fanoutStatusCommand,
|
|
61970
62334
|
handoff: handoffCommand,
|
|
61971
62335
|
"spawn-execute": spawnExecuteCommand,
|
|
@@ -62168,7 +62532,7 @@ var phase_exports = {};
|
|
|
62168
62532
|
__export(phase_exports, {
|
|
62169
62533
|
phaseCommand: () => phaseCommand
|
|
62170
62534
|
});
|
|
62171
|
-
var showCommand10, listCommand15, setCommand2, startCommand6, completeCommand3,
|
|
62535
|
+
var showCommand10, listCommand15, setCommand2, startCommand6, completeCommand3, advanceCommand3, renameCommand, deleteCommand2, phaseCommand;
|
|
62172
62536
|
var init_phase = __esm({
|
|
62173
62537
|
"packages/cleo/src/cli/commands/phase.ts"() {
|
|
62174
62538
|
"use strict";
|
|
@@ -62268,7 +62632,7 @@ var init_phase = __esm({
|
|
|
62268
62632
|
);
|
|
62269
62633
|
}
|
|
62270
62634
|
});
|
|
62271
|
-
|
|
62635
|
+
advanceCommand3 = defineCommand({
|
|
62272
62636
|
meta: { name: "advance", description: "Complete current phase and start next" },
|
|
62273
62637
|
args: {
|
|
62274
62638
|
force: {
|
|
@@ -62350,7 +62714,7 @@ var init_phase = __esm({
|
|
|
62350
62714
|
set: setCommand2,
|
|
62351
62715
|
start: startCommand6,
|
|
62352
62716
|
complete: completeCommand3,
|
|
62353
|
-
advance:
|
|
62717
|
+
advance: advanceCommand3,
|
|
62354
62718
|
rename: renameCommand,
|
|
62355
62719
|
delete: deleteCommand2
|
|
62356
62720
|
},
|
|
@@ -63350,7 +63714,7 @@ var refresh_memory_exports = {};
|
|
|
63350
63714
|
__export(refresh_memory_exports, {
|
|
63351
63715
|
refreshMemoryCommand: () => refreshMemoryCommand
|
|
63352
63716
|
});
|
|
63353
|
-
import { getProjectRoot as
|
|
63717
|
+
import { getProjectRoot as getProjectRoot51 } from "@cleocode/core";
|
|
63354
63718
|
var refreshMemoryCommand;
|
|
63355
63719
|
var init_refresh_memory = __esm({
|
|
63356
63720
|
"packages/cleo/src/cli/commands/refresh-memory.ts"() {
|
|
@@ -63363,7 +63727,7 @@ var init_refresh_memory = __esm({
|
|
|
63363
63727
|
description: "Regenerate .cleo/memory-bridge.md from brain.db"
|
|
63364
63728
|
},
|
|
63365
63729
|
async run() {
|
|
63366
|
-
const projectDir =
|
|
63730
|
+
const projectDir = getProjectRoot51();
|
|
63367
63731
|
const { writeMemoryBridge } = await import("@cleocode/core/internal");
|
|
63368
63732
|
const result = await writeMemoryBridge(projectDir);
|
|
63369
63733
|
if (result.written) {
|
|
@@ -64890,7 +65254,7 @@ import fs3 from "node:fs";
|
|
|
64890
65254
|
import path5 from "node:path";
|
|
64891
65255
|
import {
|
|
64892
65256
|
CleoError as CleoError8,
|
|
64893
|
-
getProjectRoot as
|
|
65257
|
+
getProjectRoot as getProjectRoot52,
|
|
64894
65258
|
getTaskAccessor as getTaskAccessor3,
|
|
64895
65259
|
parseConflictReport,
|
|
64896
65260
|
setAtPath
|
|
@@ -64911,7 +65275,7 @@ var init_restore = __esm({
|
|
|
64911
65275
|
description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
|
|
64912
65276
|
},
|
|
64913
65277
|
async run() {
|
|
64914
|
-
const projectRoot =
|
|
65278
|
+
const projectRoot = getProjectRoot52();
|
|
64915
65279
|
const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
|
|
64916
65280
|
if (!fs3.existsSync(reportPath)) {
|
|
64917
65281
|
humanLine("No pending restore conflicts. Nothing to finalize.");
|
|
@@ -65609,7 +65973,7 @@ __export(saga_exports, {
|
|
|
65609
65973
|
sagaCommand: () => sagaCommand
|
|
65610
65974
|
});
|
|
65611
65975
|
import { parseAcceptanceCriteria } from "@cleocode/core";
|
|
65612
|
-
var createCommand3, addCommand12, detachCommand2, listCommand22, membersCommand, repairCommand, reconcileCommand5, rollupCommand2, sagaCommand;
|
|
65976
|
+
var createCommand3, addCommand12, detachCommand2, listCommand22, membersCommand, repairCommand, reconcileCommand5, rollupCommand2, nextCommand3, sagaCommand;
|
|
65613
65977
|
var init_saga = __esm({
|
|
65614
65978
|
"packages/cleo/src/cli/commands/saga.ts"() {
|
|
65615
65979
|
"use strict";
|
|
@@ -65820,6 +66184,26 @@ var init_saga = __esm({
|
|
|
65820
66184
|
cliOutput(response.data ?? {}, { command: "saga", operation: "tasks.saga.rollup" });
|
|
65821
66185
|
}
|
|
65822
66186
|
});
|
|
66187
|
+
nextCommand3 = defineCommand({
|
|
66188
|
+
meta: {
|
|
66189
|
+
name: "next",
|
|
66190
|
+
description: "Return the next actionable Saga and its ready-frontier task IDs"
|
|
66191
|
+
},
|
|
66192
|
+
args: {
|
|
66193
|
+
sagaId: {
|
|
66194
|
+
type: "positional",
|
|
66195
|
+
description: "Optional saga task ID. Omit to auto-select from canonical order.",
|
|
66196
|
+
required: false
|
|
66197
|
+
}
|
|
66198
|
+
},
|
|
66199
|
+
async run({ args }) {
|
|
66200
|
+
const { sagas: sagas2, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
66201
|
+
const projectRoot = getProjectRoot58();
|
|
66202
|
+
const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
|
|
66203
|
+
const result = await sagas2.sagaNext(projectRoot, { sagaId });
|
|
66204
|
+
cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
|
|
66205
|
+
}
|
|
66206
|
+
});
|
|
65823
66207
|
sagaCommand = defineCommand({
|
|
65824
66208
|
meta: {
|
|
65825
66209
|
name: "saga",
|
|
@@ -65833,7 +66217,8 @@ var init_saga = __esm({
|
|
|
65833
66217
|
members: membersCommand,
|
|
65834
66218
|
rollup: rollupCommand2,
|
|
65835
66219
|
repair: repairCommand,
|
|
65836
|
-
reconcile: reconcileCommand5
|
|
66220
|
+
reconcile: reconcileCommand5,
|
|
66221
|
+
next: nextCommand3
|
|
65837
66222
|
},
|
|
65838
66223
|
async run({ cmd, rawArgs }) {
|
|
65839
66224
|
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|
|
@@ -66075,7 +66460,7 @@ async function writeRuntimeVersionMetadata(mode, source, version) {
|
|
|
66075
66460
|
`installed=${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
66076
66461
|
];
|
|
66077
66462
|
await import("node:fs/promises").then(
|
|
66078
|
-
({ writeFile: writeFile4, mkdir:
|
|
66463
|
+
({ writeFile: writeFile4, mkdir: mkdir6 }) => mkdir6(cleoHome, { recursive: true }).then(
|
|
66079
66464
|
() => writeFile4(join29(cleoHome, "VERSION"), `${lines.join("\n")}
|
|
66080
66465
|
`, "utf-8")
|
|
66081
66466
|
)
|
|
@@ -67555,7 +67940,7 @@ var sequence_exports = {};
|
|
|
67555
67940
|
__export(sequence_exports, {
|
|
67556
67941
|
sequenceCommand: () => sequenceCommand
|
|
67557
67942
|
});
|
|
67558
|
-
import { getProjectRoot as
|
|
67943
|
+
import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/internal";
|
|
67559
67944
|
var showCommand13, checkCommand7, repairCommand2, sequenceCommand;
|
|
67560
67945
|
var init_sequence = __esm({
|
|
67561
67946
|
"packages/cleo/src/cli/commands/sequence.ts"() {
|
|
@@ -67591,7 +67976,7 @@ var init_sequence = __esm({
|
|
|
67591
67976
|
meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
|
|
67592
67977
|
async run() {
|
|
67593
67978
|
const { repairSequence } = await import("@cleocode/core/internal");
|
|
67594
|
-
const projectRoot =
|
|
67979
|
+
const projectRoot = getProjectRoot53();
|
|
67595
67980
|
const repair = await repairSequence(projectRoot);
|
|
67596
67981
|
const result = {
|
|
67597
67982
|
repaired: repair.repaired,
|
|
@@ -68046,8 +68431,8 @@ var init_session4 = __esm({
|
|
|
68046
68431
|
"audit-scope": { type: "string", description: "Audit log scope (global|local)" }
|
|
68047
68432
|
},
|
|
68048
68433
|
async run({ args }) {
|
|
68049
|
-
const { detectSessionDrift, getProjectRoot:
|
|
68050
|
-
const projectRoot = await
|
|
68434
|
+
const { detectSessionDrift, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
68435
|
+
const projectRoot = await getProjectRoot58();
|
|
68051
68436
|
const scope = args["audit-scope"] === "local" ? "local" : "global";
|
|
68052
68437
|
const report = await detectSessionDrift({ projectRoot, auditScope: scope });
|
|
68053
68438
|
cliOutput(report, { command: "session drift", operation: "session.drift" });
|
|
@@ -70744,13 +71129,13 @@ var init_telemetry2 = __esm({
|
|
|
70744
71129
|
// packages/cleo/src/cli/commands/templates/lib.ts
|
|
70745
71130
|
import { readFileSync as readFileSync15 } from "node:fs";
|
|
70746
71131
|
import { isAbsolute as isAbsolute3, resolve as resolve8 } from "node:path";
|
|
70747
|
-
import { getProjectRoot as
|
|
71132
|
+
import { getProjectRoot as getProjectRoot54 } from "@cleocode/core";
|
|
70748
71133
|
import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
|
|
70749
71134
|
function resolveProjectRoot6(raw) {
|
|
70750
71135
|
if (typeof raw === "string" && raw.length > 0) {
|
|
70751
71136
|
return isAbsolute3(raw) ? raw : resolve8(process.cwd(), raw);
|
|
70752
71137
|
}
|
|
70753
|
-
return
|
|
71138
|
+
return getProjectRoot54();
|
|
70754
71139
|
}
|
|
70755
71140
|
function readTemplateSource(entry) {
|
|
70756
71141
|
const sourceAbsolute = resolveSourcePathAbsolute(entry);
|
|
@@ -71534,7 +71919,7 @@ __export(token_exports, {
|
|
|
71534
71919
|
tokenCommand: () => tokenCommand
|
|
71535
71920
|
});
|
|
71536
71921
|
import { readFileSync as readFileSync19 } from "node:fs";
|
|
71537
|
-
import { getProjectRoot as
|
|
71922
|
+
import { getProjectRoot as getProjectRoot55, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
|
|
71538
71923
|
function readPayload(args, textKey, fileKey) {
|
|
71539
71924
|
const text = args[textKey];
|
|
71540
71925
|
const file = args[fileKey];
|
|
@@ -71698,7 +72083,7 @@ var init_token = __esm({
|
|
|
71698
72083
|
domain: args.domain,
|
|
71699
72084
|
operation: args.operation
|
|
71700
72085
|
};
|
|
71701
|
-
const result = args.record ? await recordTokenExchange2(
|
|
72086
|
+
const result = args.record ? await recordTokenExchange2(getProjectRoot55(), input2) : await measureTokenExchange(input2);
|
|
71702
72087
|
cliOutput(result, {
|
|
71703
72088
|
command: "token",
|
|
71704
72089
|
operation: args.record ? "admin.token.record" : "token.estimate"
|
|
@@ -71734,7 +72119,7 @@ __export(transcript_exports, {
|
|
|
71734
72119
|
});
|
|
71735
72120
|
import { homedir as homedir6 } from "node:os";
|
|
71736
72121
|
import { join as join34 } from "node:path";
|
|
71737
|
-
import { getProjectRoot as
|
|
72122
|
+
import { getProjectRoot as getProjectRoot56 } from "@cleocode/core";
|
|
71738
72123
|
import {
|
|
71739
72124
|
parseDurationMs,
|
|
71740
72125
|
pruneTranscripts,
|
|
@@ -71764,7 +72149,7 @@ var init_transcript = __esm({
|
|
|
71764
72149
|
async run({ args }) {
|
|
71765
72150
|
if (args.pending) {
|
|
71766
72151
|
try {
|
|
71767
|
-
const projectRoot =
|
|
72152
|
+
const projectRoot = getProjectRoot56();
|
|
71768
72153
|
const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
|
|
71769
72154
|
const pending = await scanPendingTranscripts(projectRoot);
|
|
71770
72155
|
cliOutput(
|
|
@@ -71861,7 +72246,7 @@ var init_transcript = __esm({
|
|
|
71861
72246
|
async run({ args }) {
|
|
71862
72247
|
const tier = args.tier ?? "warm";
|
|
71863
72248
|
const dryRun = args["dry-run"] ?? false;
|
|
71864
|
-
const projectRoot =
|
|
72249
|
+
const projectRoot = getProjectRoot56();
|
|
71865
72250
|
try {
|
|
71866
72251
|
const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
|
|
71867
72252
|
const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
|
|
@@ -71973,7 +72358,7 @@ var init_transcript = __esm({
|
|
|
71973
72358
|
const dryRun = args["dry-run"] ?? false;
|
|
71974
72359
|
const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
|
|
71975
72360
|
const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
|
|
71976
|
-
const projectRoot =
|
|
72361
|
+
const projectRoot = getProjectRoot56();
|
|
71977
72362
|
try {
|
|
71978
72363
|
const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
|
|
71979
72364
|
const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
|
|
@@ -72919,15 +73304,12 @@ var init_verify = __esm({
|
|
|
72919
73304
|
}
|
|
72920
73305
|
});
|
|
72921
73306
|
|
|
72922
|
-
// packages/cleo/src/cli/
|
|
72923
|
-
var web_exports = {};
|
|
72924
|
-
__export(web_exports, {
|
|
72925
|
-
webCommand: () => webCommand
|
|
72926
|
-
});
|
|
73307
|
+
// packages/cleo/src/cli/web-subsystem.ts
|
|
72927
73308
|
import { execFileSync as execFileSync4, spawn as spawn3 } from "node:child_process";
|
|
72928
|
-
import { mkdir as
|
|
73309
|
+
import { mkdir as mkdir5, open, readFile as readFile8, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
72929
73310
|
import { join as join35 } from "node:path";
|
|
72930
|
-
import {
|
|
73311
|
+
import { getCleoHome as getCleoHome5 } from "@cleocode/core";
|
|
73312
|
+
import { defineSubsystem as defineSubsystem2 } from "@cleocode/runtime/daemon";
|
|
72931
73313
|
function getWebPaths() {
|
|
72932
73314
|
const cleoHome = getCleoHome5();
|
|
72933
73315
|
return {
|
|
@@ -72937,7 +73319,7 @@ function getWebPaths() {
|
|
|
72937
73319
|
logFile: join35(cleoHome, "logs", "web-server.log")
|
|
72938
73320
|
};
|
|
72939
73321
|
}
|
|
72940
|
-
function
|
|
73322
|
+
function isWebProcessRunning(pid) {
|
|
72941
73323
|
try {
|
|
72942
73324
|
process.kill(pid, 0);
|
|
72943
73325
|
return true;
|
|
@@ -72945,20 +73327,20 @@ function isProcessRunning(pid) {
|
|
|
72945
73327
|
return false;
|
|
72946
73328
|
}
|
|
72947
73329
|
}
|
|
72948
|
-
async function
|
|
73330
|
+
async function getWebStatus() {
|
|
72949
73331
|
const { pidFile, configFile } = getWebPaths();
|
|
72950
73332
|
try {
|
|
72951
73333
|
const pidStr = (await readFile8(pidFile, "utf-8")).trim();
|
|
72952
73334
|
const pid = Number.parseInt(pidStr, 10);
|
|
72953
|
-
if (Number.isNaN(pid) || !
|
|
73335
|
+
if (Number.isNaN(pid) || !isWebProcessRunning(pid)) {
|
|
72954
73336
|
return { running: false, pid: null, port: null, host: null, url: null };
|
|
72955
73337
|
}
|
|
72956
|
-
let port =
|
|
72957
|
-
let host =
|
|
73338
|
+
let port = WEB_DEFAULT_PORT;
|
|
73339
|
+
let host = WEB_DEFAULT_HOST;
|
|
72958
73340
|
try {
|
|
72959
73341
|
const config = JSON.parse(await readFile8(configFile, "utf-8"));
|
|
72960
|
-
port = config.port ??
|
|
72961
|
-
host = config.host ??
|
|
73342
|
+
port = config.port ?? WEB_DEFAULT_PORT;
|
|
73343
|
+
host = config.host ?? WEB_DEFAULT_HOST;
|
|
72962
73344
|
} catch {
|
|
72963
73345
|
}
|
|
72964
73346
|
return { running: true, pid, port, host, url: `http://${host}:${port}` };
|
|
@@ -72966,118 +73348,212 @@ async function getStatus() {
|
|
|
72966
73348
|
return { running: false, pid: null, port: null, host: null, url: null };
|
|
72967
73349
|
}
|
|
72968
73350
|
}
|
|
72969
|
-
|
|
72970
|
-
const
|
|
72971
|
-
const
|
|
72972
|
-
|
|
72973
|
-
|
|
72974
|
-
|
|
72975
|
-
|
|
72976
|
-
|
|
72977
|
-
|
|
72978
|
-
|
|
72979
|
-
|
|
72980
|
-
|
|
72981
|
-
|
|
72982
|
-
|
|
72983
|
-
|
|
72984
|
-
|
|
72985
|
-
|
|
72986
|
-
|
|
72987
|
-
|
|
72988
|
-
|
|
72989
|
-
|
|
72990
|
-
|
|
72991
|
-
|
|
72992
|
-
|
|
72993
|
-
|
|
72994
|
-
|
|
72995
|
-
|
|
72996
|
-
throw new CleoError12(
|
|
72997
|
-
1 /* GENERAL_ERROR */,
|
|
72998
|
-
`Studio build failed. Run: pnpm --filter @cleocode/studio run build
|
|
72999
|
-
Logs: ${logFile}`
|
|
73351
|
+
function createWebSubsystem(opts = {}) {
|
|
73352
|
+
const port = opts.port ?? WEB_DEFAULT_PORT;
|
|
73353
|
+
const host = opts.host ?? WEB_DEFAULT_HOST;
|
|
73354
|
+
let live;
|
|
73355
|
+
return defineSubsystem2({
|
|
73356
|
+
name: WEB_SUBSYSTEM_NAME,
|
|
73357
|
+
async start() {
|
|
73358
|
+
const { pidFile, configFile, logFile, logDir } = getWebPaths();
|
|
73359
|
+
const existing = await getWebStatus();
|
|
73360
|
+
if (existing.running && existing.pid !== null) {
|
|
73361
|
+
const ctx2 = {
|
|
73362
|
+
pid: existing.pid,
|
|
73363
|
+
pidFile,
|
|
73364
|
+
logFile,
|
|
73365
|
+
port: existing.port ?? port,
|
|
73366
|
+
host: existing.host ?? host
|
|
73367
|
+
};
|
|
73368
|
+
live = ctx2;
|
|
73369
|
+
return ctx2;
|
|
73370
|
+
}
|
|
73371
|
+
const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
|
|
73372
|
+
const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join35(projectRoot, "packages", "studio", "build");
|
|
73373
|
+
const webIndexPath = join35(studioDir, "index.js");
|
|
73374
|
+
await mkdir5(logDir, { recursive: true });
|
|
73375
|
+
await writeFile3(
|
|
73376
|
+
configFile,
|
|
73377
|
+
JSON.stringify({ port, host, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
73000
73378
|
);
|
|
73001
|
-
|
|
73002
|
-
|
|
73003
|
-
|
|
73004
|
-
|
|
73005
|
-
|
|
73006
|
-
|
|
73007
|
-
|
|
73008
|
-
|
|
73009
|
-
|
|
73010
|
-
|
|
73011
|
-
|
|
73379
|
+
try {
|
|
73380
|
+
await stat2(webIndexPath);
|
|
73381
|
+
} catch {
|
|
73382
|
+
try {
|
|
73383
|
+
execFileSync4("pnpm", ["--filter", "@cleocode/studio", "run", "build"], {
|
|
73384
|
+
cwd: projectRoot,
|
|
73385
|
+
stdio: "ignore"
|
|
73386
|
+
});
|
|
73387
|
+
} catch {
|
|
73388
|
+
throw new Error(
|
|
73389
|
+
`Studio build failed. Run: pnpm --filter @cleocode/studio run build
|
|
73390
|
+
Logs: ${logFile}`
|
|
73391
|
+
);
|
|
73392
|
+
}
|
|
73393
|
+
}
|
|
73394
|
+
const logFileHandle = await open(logFile, "a");
|
|
73395
|
+
const serverProcess = spawn3("node", [webIndexPath], {
|
|
73396
|
+
cwd: studioDir,
|
|
73397
|
+
env: {
|
|
73398
|
+
...process.env,
|
|
73399
|
+
HOST: host,
|
|
73400
|
+
PORT: String(port),
|
|
73401
|
+
CLEO_ROOT: projectRoot
|
|
73402
|
+
},
|
|
73403
|
+
detached: true,
|
|
73404
|
+
stdio: ["ignore", logFileHandle.fd, logFileHandle.fd]
|
|
73405
|
+
});
|
|
73406
|
+
serverProcess.unref();
|
|
73407
|
+
const pidFileTmp = `${pidFile}.tmp`;
|
|
73408
|
+
await writeFile3(pidFileTmp, String(serverProcess.pid));
|
|
73409
|
+
await rm(pidFile, { force: true });
|
|
73410
|
+
await writeFile3(pidFile, String(serverProcess.pid));
|
|
73411
|
+
await rm(pidFileTmp, { force: true });
|
|
73412
|
+
await logFileHandle.close();
|
|
73413
|
+
let started = false;
|
|
73414
|
+
for (let i = 0; i < STARTUP_POLL_ITERATIONS; i++) {
|
|
73415
|
+
try {
|
|
73416
|
+
const response = await fetch(`http://${host}:${port}/api/health`);
|
|
73417
|
+
if (response.ok) {
|
|
73418
|
+
started = true;
|
|
73419
|
+
break;
|
|
73420
|
+
}
|
|
73421
|
+
} catch {
|
|
73422
|
+
}
|
|
73423
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
73424
|
+
}
|
|
73425
|
+
if (!started) {
|
|
73426
|
+
try {
|
|
73427
|
+
process.kill(serverProcess.pid, "SIGTERM");
|
|
73428
|
+
} catch {
|
|
73429
|
+
}
|
|
73430
|
+
await rm(pidFile, { force: true });
|
|
73431
|
+
throw new Error("Studio web server failed to start within 15 seconds");
|
|
73432
|
+
}
|
|
73433
|
+
const ctx = {
|
|
73434
|
+
pid: serverProcess.pid,
|
|
73435
|
+
pidFile,
|
|
73436
|
+
logFile,
|
|
73437
|
+
port,
|
|
73438
|
+
host
|
|
73439
|
+
};
|
|
73440
|
+
live = ctx;
|
|
73441
|
+
return ctx;
|
|
73012
73442
|
},
|
|
73013
|
-
|
|
73014
|
-
|
|
73015
|
-
|
|
73016
|
-
|
|
73017
|
-
|
|
73018
|
-
|
|
73019
|
-
|
|
73020
|
-
|
|
73021
|
-
|
|
73022
|
-
|
|
73023
|
-
const maxAttempts = 30;
|
|
73024
|
-
let started = false;
|
|
73025
|
-
for (let i = 0; i < maxAttempts; i++) {
|
|
73026
|
-
try {
|
|
73027
|
-
const response = await fetch(`http://${host}:${port}/api/health`);
|
|
73028
|
-
if (response.ok) {
|
|
73029
|
-
started = true;
|
|
73030
|
-
break;
|
|
73443
|
+
healthProbe() {
|
|
73444
|
+
if (live === void 0) {
|
|
73445
|
+
const stopped = "stopped";
|
|
73446
|
+
return {
|
|
73447
|
+
child_id: WEB_SUBSYSTEM_NAME,
|
|
73448
|
+
pid: 0,
|
|
73449
|
+
state: stopped,
|
|
73450
|
+
restart_count: 0,
|
|
73451
|
+
detail: "not started"
|
|
73452
|
+
};
|
|
73031
73453
|
}
|
|
73032
|
-
|
|
73033
|
-
|
|
73034
|
-
|
|
73035
|
-
|
|
73036
|
-
|
|
73037
|
-
|
|
73038
|
-
|
|
73039
|
-
|
|
73040
|
-
|
|
73041
|
-
await rm(pidFile, { force: true });
|
|
73042
|
-
throw new CleoError12(1 /* GENERAL_ERROR */, "Server failed to start within 15 seconds");
|
|
73043
|
-
}
|
|
73044
|
-
cliOutput(
|
|
73045
|
-
{
|
|
73046
|
-
pid: serverProcess.pid,
|
|
73047
|
-
port,
|
|
73048
|
-
host,
|
|
73049
|
-
url: `http://${host}:${port}`,
|
|
73050
|
-
logFile
|
|
73454
|
+
const alive = isWebProcessRunning(live.pid);
|
|
73455
|
+
const state = alive ? "running" : "stopped";
|
|
73456
|
+
return {
|
|
73457
|
+
child_id: WEB_SUBSYSTEM_NAME,
|
|
73458
|
+
pid: alive ? live.pid : 0,
|
|
73459
|
+
state,
|
|
73460
|
+
restart_count: 0,
|
|
73461
|
+
detail: alive ? `url=http://${live.host}:${live.port} pid=${live.pid}` : `pid=${live.pid} exited`
|
|
73462
|
+
};
|
|
73051
73463
|
},
|
|
73052
|
-
|
|
73053
|
-
|
|
73464
|
+
async shutdown(context) {
|
|
73465
|
+
const { pidFile } = context;
|
|
73466
|
+
if (!isWebProcessRunning(context.pid)) {
|
|
73467
|
+
await rm(pidFile, { force: true });
|
|
73468
|
+
live = void 0;
|
|
73469
|
+
return;
|
|
73470
|
+
}
|
|
73471
|
+
try {
|
|
73472
|
+
if (process.platform === "win32") {
|
|
73473
|
+
spawn3("taskkill", ["/PID", String(context.pid), "/T"], { stdio: "ignore" });
|
|
73474
|
+
} else {
|
|
73475
|
+
process.kill(context.pid, "SIGTERM");
|
|
73476
|
+
}
|
|
73477
|
+
} catch {
|
|
73478
|
+
}
|
|
73479
|
+
for (let i = 0; i < SIGTERM_GRACE_ITERATIONS2; i++) {
|
|
73480
|
+
if (!isWebProcessRunning(context.pid)) break;
|
|
73481
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
73482
|
+
}
|
|
73483
|
+
if (isWebProcessRunning(context.pid)) {
|
|
73484
|
+
try {
|
|
73485
|
+
if (process.platform === "win32") {
|
|
73486
|
+
spawn3("taskkill", ["/PID", String(context.pid), "/F", "/T"], { stdio: "ignore" });
|
|
73487
|
+
} else {
|
|
73488
|
+
process.kill(context.pid, "SIGKILL");
|
|
73489
|
+
}
|
|
73490
|
+
} catch {
|
|
73491
|
+
}
|
|
73492
|
+
}
|
|
73493
|
+
await rm(pidFile, { force: true });
|
|
73494
|
+
live = void 0;
|
|
73495
|
+
}
|
|
73496
|
+
});
|
|
73054
73497
|
}
|
|
73055
|
-
var
|
|
73498
|
+
var WEB_DEFAULT_PORT, WEB_DEFAULT_HOST, WEB_SUBSYSTEM_NAME, SIGTERM_GRACE_ITERATIONS2, STARTUP_POLL_ITERATIONS;
|
|
73499
|
+
var init_web_subsystem = __esm({
|
|
73500
|
+
"packages/cleo/src/cli/web-subsystem.ts"() {
|
|
73501
|
+
"use strict";
|
|
73502
|
+
WEB_DEFAULT_PORT = 3456;
|
|
73503
|
+
WEB_DEFAULT_HOST = "127.0.0.1";
|
|
73504
|
+
WEB_SUBSYSTEM_NAME = "cleo-web";
|
|
73505
|
+
SIGTERM_GRACE_ITERATIONS2 = 60;
|
|
73506
|
+
STARTUP_POLL_ITERATIONS = 30;
|
|
73507
|
+
}
|
|
73508
|
+
});
|
|
73509
|
+
|
|
73510
|
+
// packages/cleo/src/cli/commands/web.ts
|
|
73511
|
+
var web_exports = {};
|
|
73512
|
+
__export(web_exports, {
|
|
73513
|
+
webCommand: () => webCommand
|
|
73514
|
+
});
|
|
73515
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
73516
|
+
import { rm as rm2 } from "node:fs/promises";
|
|
73517
|
+
import { CleoError as CleoError12, formatError as formatError5 } from "@cleocode/core";
|
|
73518
|
+
var startCommand9, stopCommand6, restartCommand, statusCommand18, openCommand3, webCommand;
|
|
73056
73519
|
var init_web = __esm({
|
|
73057
73520
|
"packages/cleo/src/cli/commands/web.ts"() {
|
|
73058
73521
|
"use strict";
|
|
73059
73522
|
init_src2();
|
|
73060
73523
|
init_dist();
|
|
73061
73524
|
init_renderers();
|
|
73062
|
-
|
|
73063
|
-
DEFAULT_HOST = "127.0.0.1";
|
|
73525
|
+
init_web_subsystem();
|
|
73064
73526
|
startCommand9 = defineCommand({
|
|
73065
73527
|
meta: { name: "start", description: "Start the web server" },
|
|
73066
73528
|
args: {
|
|
73067
73529
|
port: {
|
|
73068
73530
|
type: "string",
|
|
73069
73531
|
description: "Server port",
|
|
73070
|
-
default: String(
|
|
73532
|
+
default: String(WEB_DEFAULT_PORT)
|
|
73071
73533
|
},
|
|
73072
73534
|
host: {
|
|
73073
73535
|
type: "string",
|
|
73074
73536
|
description: "Server host",
|
|
73075
|
-
default:
|
|
73537
|
+
default: WEB_DEFAULT_HOST
|
|
73076
73538
|
}
|
|
73077
73539
|
},
|
|
73078
73540
|
async run({ args }) {
|
|
73079
73541
|
try {
|
|
73080
|
-
|
|
73542
|
+
const port = Number.parseInt(args.port, 10);
|
|
73543
|
+
const host = args.host;
|
|
73544
|
+
const subsystem = createWebSubsystem({ port, host });
|
|
73545
|
+
const ctx = await subsystem.start();
|
|
73546
|
+
const { logFile } = getWebPaths();
|
|
73547
|
+
cliOutput(
|
|
73548
|
+
{
|
|
73549
|
+
pid: ctx.pid,
|
|
73550
|
+
port: ctx.port,
|
|
73551
|
+
host: ctx.host,
|
|
73552
|
+
url: `http://${ctx.host}:${ctx.port}`,
|
|
73553
|
+
logFile
|
|
73554
|
+
},
|
|
73555
|
+
{ command: "web", message: `CLEO Web UI running on port ${ctx.port}` }
|
|
73556
|
+
);
|
|
73081
73557
|
} catch (err) {
|
|
73082
73558
|
if (err instanceof CleoError12) {
|
|
73083
73559
|
console.error(formatError5(err));
|
|
@@ -73091,36 +73567,24 @@ var init_web = __esm({
|
|
|
73091
73567
|
meta: { name: "stop", description: "Stop the web server" },
|
|
73092
73568
|
async run() {
|
|
73093
73569
|
try {
|
|
73094
|
-
const { pidFile } = getWebPaths();
|
|
73095
|
-
const status = await
|
|
73096
|
-
if (!status.running ||
|
|
73097
|
-
await
|
|
73570
|
+
const { pidFile, logFile } = getWebPaths();
|
|
73571
|
+
const status = await getWebStatus();
|
|
73572
|
+
if (!status.running || status.pid === null) {
|
|
73573
|
+
await rm2(pidFile, { force: true });
|
|
73098
73574
|
cliOutput({ running: false }, { command: "web", message: "Server is not running" });
|
|
73099
73575
|
return;
|
|
73100
73576
|
}
|
|
73101
|
-
|
|
73102
|
-
|
|
73103
|
-
|
|
73104
|
-
|
|
73105
|
-
|
|
73106
|
-
|
|
73107
|
-
|
|
73108
|
-
|
|
73109
|
-
|
|
73110
|
-
|
|
73111
|
-
|
|
73112
|
-
}
|
|
73113
|
-
if (isProcessRunning(status.pid)) {
|
|
73114
|
-
try {
|
|
73115
|
-
if (process.platform === "win32") {
|
|
73116
|
-
spawn3("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
|
|
73117
|
-
} else {
|
|
73118
|
-
process.kill(status.pid, "SIGKILL");
|
|
73119
|
-
}
|
|
73120
|
-
} catch {
|
|
73121
|
-
}
|
|
73122
|
-
}
|
|
73123
|
-
await rm(pidFile, { force: true });
|
|
73577
|
+
const subsystem = createWebSubsystem({
|
|
73578
|
+
port: status.port ?? WEB_DEFAULT_PORT,
|
|
73579
|
+
host: status.host ?? WEB_DEFAULT_HOST
|
|
73580
|
+
});
|
|
73581
|
+
await subsystem.shutdown({
|
|
73582
|
+
pid: status.pid,
|
|
73583
|
+
pidFile,
|
|
73584
|
+
logFile,
|
|
73585
|
+
port: status.port ?? WEB_DEFAULT_PORT,
|
|
73586
|
+
host: status.host ?? WEB_DEFAULT_HOST
|
|
73587
|
+
});
|
|
73124
73588
|
cliOutput({ stopped: true }, { command: "web", message: "CLEO Web UI stopped" });
|
|
73125
73589
|
} catch (err) {
|
|
73126
73590
|
if (err instanceof CleoError12) {
|
|
@@ -73137,44 +73601,45 @@ var init_web = __esm({
|
|
|
73137
73601
|
port: {
|
|
73138
73602
|
type: "string",
|
|
73139
73603
|
description: "Server port",
|
|
73140
|
-
default: String(
|
|
73604
|
+
default: String(WEB_DEFAULT_PORT)
|
|
73141
73605
|
},
|
|
73142
73606
|
host: {
|
|
73143
73607
|
type: "string",
|
|
73144
73608
|
description: "Server host",
|
|
73145
|
-
default:
|
|
73609
|
+
default: WEB_DEFAULT_HOST
|
|
73146
73610
|
}
|
|
73147
73611
|
},
|
|
73148
73612
|
async run({ args }) {
|
|
73149
73613
|
try {
|
|
73150
|
-
const
|
|
73151
|
-
const
|
|
73152
|
-
|
|
73153
|
-
|
|
73154
|
-
|
|
73155
|
-
|
|
73156
|
-
|
|
73157
|
-
|
|
73158
|
-
|
|
73159
|
-
|
|
73160
|
-
|
|
73161
|
-
|
|
73162
|
-
|
|
73163
|
-
|
|
73164
|
-
|
|
73165
|
-
|
|
73166
|
-
try {
|
|
73167
|
-
if (process.platform === "win32") {
|
|
73168
|
-
spawn3("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
|
|
73169
|
-
} else {
|
|
73170
|
-
process.kill(status.pid, "SIGKILL");
|
|
73171
|
-
}
|
|
73172
|
-
} catch {
|
|
73173
|
-
}
|
|
73174
|
-
}
|
|
73175
|
-
await rm(pidFile, { force: true });
|
|
73614
|
+
const port = Number.parseInt(args.port, 10);
|
|
73615
|
+
const host = args.host;
|
|
73616
|
+
const { pidFile, logFile } = getWebPaths();
|
|
73617
|
+
const status = await getWebStatus();
|
|
73618
|
+
if (status.running && status.pid !== null) {
|
|
73619
|
+
const stopSubsystem = createWebSubsystem({
|
|
73620
|
+
port: status.port ?? port,
|
|
73621
|
+
host: status.host ?? host
|
|
73622
|
+
});
|
|
73623
|
+
await stopSubsystem.shutdown({
|
|
73624
|
+
pid: status.pid,
|
|
73625
|
+
pidFile,
|
|
73626
|
+
logFile,
|
|
73627
|
+
port: status.port ?? port,
|
|
73628
|
+
host: status.host ?? host
|
|
73629
|
+
});
|
|
73176
73630
|
}
|
|
73177
|
-
|
|
73631
|
+
const startSubsystem = createWebSubsystem({ port, host });
|
|
73632
|
+
const ctx = await startSubsystem.start();
|
|
73633
|
+
cliOutput(
|
|
73634
|
+
{
|
|
73635
|
+
pid: ctx.pid,
|
|
73636
|
+
port: ctx.port,
|
|
73637
|
+
host: ctx.host,
|
|
73638
|
+
url: `http://${ctx.host}:${ctx.port}`,
|
|
73639
|
+
logFile
|
|
73640
|
+
},
|
|
73641
|
+
{ command: "web", message: `CLEO Web UI running on port ${ctx.port}` }
|
|
73642
|
+
);
|
|
73178
73643
|
} catch (err) {
|
|
73179
73644
|
if (err instanceof CleoError12) {
|
|
73180
73645
|
console.error(formatError5(err));
|
|
@@ -73188,7 +73653,7 @@ var init_web = __esm({
|
|
|
73188
73653
|
meta: { name: "status", description: "Check server status" },
|
|
73189
73654
|
async run() {
|
|
73190
73655
|
try {
|
|
73191
|
-
const status = await
|
|
73656
|
+
const status = await getWebStatus();
|
|
73192
73657
|
cliOutput(status, { command: "web" });
|
|
73193
73658
|
} catch (err) {
|
|
73194
73659
|
if (err instanceof CleoError12) {
|
|
@@ -73203,7 +73668,7 @@ var init_web = __esm({
|
|
|
73203
73668
|
meta: { name: "open", description: "Open browser to the UI" },
|
|
73204
73669
|
async run() {
|
|
73205
73670
|
try {
|
|
73206
|
-
const status = await
|
|
73671
|
+
const status = await getWebStatus();
|
|
73207
73672
|
if (!status.running || !status.url) {
|
|
73208
73673
|
throw new CleoError12(
|
|
73209
73674
|
1 /* GENERAL_ERROR */,
|
|
@@ -73214,11 +73679,11 @@ var init_web = __esm({
|
|
|
73214
73679
|
const platform = process.platform;
|
|
73215
73680
|
try {
|
|
73216
73681
|
if (platform === "linux") {
|
|
73217
|
-
|
|
73682
|
+
spawn4("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
|
|
73218
73683
|
} else if (platform === "darwin") {
|
|
73219
|
-
|
|
73684
|
+
spawn4("open", [url], { detached: true, stdio: "ignore" }).unref();
|
|
73220
73685
|
} else if (platform === "win32") {
|
|
73221
|
-
|
|
73686
|
+
spawn4("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" }).unref();
|
|
73222
73687
|
}
|
|
73223
73688
|
} catch {
|
|
73224
73689
|
}
|
|
@@ -73257,7 +73722,7 @@ __export(workgraph_exports, {
|
|
|
73257
73722
|
});
|
|
73258
73723
|
import { readFileSync as readFileSync20 } from "node:fs";
|
|
73259
73724
|
import { resolve as resolve10 } from "node:path";
|
|
73260
|
-
var validateCommand10, applyCommand, planCommand4, structureCommand, workgraphCommand;
|
|
73725
|
+
var validateCommand10, applyCommand, planCommand4, structureCommand, statusCommand19, workgraphCommand;
|
|
73261
73726
|
var init_workgraph2 = __esm({
|
|
73262
73727
|
"packages/cleo/src/cli/commands/workgraph.ts"() {
|
|
73263
73728
|
"use strict";
|
|
@@ -73367,9 +73832,9 @@ var init_workgraph2 = __esm({
|
|
|
73367
73832
|
},
|
|
73368
73833
|
async run({ args }) {
|
|
73369
73834
|
const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
|
|
73370
|
-
const { getProjectRoot:
|
|
73835
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
73371
73836
|
const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
|
|
73372
|
-
const projectRoot =
|
|
73837
|
+
const projectRoot = getProjectRoot58();
|
|
73373
73838
|
const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
|
|
73374
73839
|
const result = await generatePlanningDoc(projectRoot, {
|
|
73375
73840
|
sagaId: String(args.sagaId),
|
|
@@ -73386,9 +73851,9 @@ var init_workgraph2 = __esm({
|
|
|
73386
73851
|
async run() {
|
|
73387
73852
|
const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
|
|
73388
73853
|
const { taskList: taskList2 } = await import("@cleocode/core/internal");
|
|
73389
|
-
const { getProjectRoot:
|
|
73854
|
+
const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
73390
73855
|
const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
|
|
73391
|
-
const projectRoot =
|
|
73856
|
+
const projectRoot = getProjectRoot58();
|
|
73392
73857
|
const listResult = await taskList2(projectRoot, { limit: 5e3 });
|
|
73393
73858
|
const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
|
|
73394
73859
|
const nodes = tasks.map((t) => ({
|
|
@@ -73401,16 +73866,64 @@ var init_workgraph2 = __esm({
|
|
|
73401
73866
|
cliOutput2(result, { command: "workgraph", operation: "structure" });
|
|
73402
73867
|
}
|
|
73403
73868
|
});
|
|
73869
|
+
statusCommand19 = defineCommand({
|
|
73870
|
+
meta: {
|
|
73871
|
+
name: "status",
|
|
73872
|
+
description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
|
|
73873
|
+
},
|
|
73874
|
+
async run() {
|
|
73875
|
+
const { sagas: sagas2, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
|
|
73876
|
+
const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
|
|
73877
|
+
const projectRoot = getProjectRoot58();
|
|
73878
|
+
const listResult = await sagas2.sagaList(projectRoot);
|
|
73879
|
+
if (!listResult.success) {
|
|
73880
|
+
cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
|
|
73881
|
+
return;
|
|
73882
|
+
}
|
|
73883
|
+
const allSagas = listResult.data?.sagas ?? [];
|
|
73884
|
+
const sagaMap = new Map(
|
|
73885
|
+
allSagas.map((s) => [s.id, s])
|
|
73886
|
+
);
|
|
73887
|
+
const TERMINAL = /* @__PURE__ */ new Set(["done", "cancelled", "deleted", "archived", "completed"]);
|
|
73888
|
+
const rows = [];
|
|
73889
|
+
for (let i = 0; i < sagas2.CANONICAL_SAGA_ORDER.length; i++) {
|
|
73890
|
+
const [id, label] = sagas2.CANONICAL_SAGA_ORDER[i];
|
|
73891
|
+
const saga = sagaMap.get(id);
|
|
73892
|
+
if (!saga) continue;
|
|
73893
|
+
const status = saga.status ?? "pending";
|
|
73894
|
+
const rollupResult = await sagas2.sagaRollup(projectRoot, { sagaId: id });
|
|
73895
|
+
const rollup = rollupResult.success ? rollupResult.data : { total: 0, done: 0, completionPct: 0 };
|
|
73896
|
+
rows.push({
|
|
73897
|
+
rank: i + 1,
|
|
73898
|
+
sagaId: id,
|
|
73899
|
+
status,
|
|
73900
|
+
completionPct: rollup.completionPct ?? 0,
|
|
73901
|
+
done: rollup.done ?? 0,
|
|
73902
|
+
total: rollup.total ?? 0,
|
|
73903
|
+
label: TERMINAL.has(status) ? `${label} \u2713` : label
|
|
73904
|
+
});
|
|
73905
|
+
}
|
|
73906
|
+
cliOutput2(
|
|
73907
|
+
{
|
|
73908
|
+
rows,
|
|
73909
|
+
total: rows.length,
|
|
73910
|
+
activeSagaCount: rows.filter((r) => !TERMINAL.has(r.status)).length
|
|
73911
|
+
},
|
|
73912
|
+
{ command: "workgraph", operation: "workgraph.status" }
|
|
73913
|
+
);
|
|
73914
|
+
}
|
|
73915
|
+
});
|
|
73404
73916
|
workgraphCommand = defineCommand({
|
|
73405
73917
|
meta: {
|
|
73406
73918
|
name: "workgraph",
|
|
73407
|
-
description: "PM-Core V2 WorkGraph operations \u2014 validate, apply, plan, structure"
|
|
73919
|
+
description: "PM-Core V2 WorkGraph operations \u2014 validate, apply, plan, structure, status"
|
|
73408
73920
|
},
|
|
73409
73921
|
subCommands: {
|
|
73410
73922
|
validate: validateCommand10,
|
|
73411
73923
|
apply: applyCommand,
|
|
73412
73924
|
plan: planCommand4,
|
|
73413
|
-
structure: structureCommand
|
|
73925
|
+
structure: structureCommand,
|
|
73926
|
+
status: statusCommand19
|
|
73414
73927
|
},
|
|
73415
73928
|
async run({ cmd, rawArgs }) {
|
|
73416
73929
|
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|
|
@@ -73427,7 +73940,7 @@ __export(worktree_exports, {
|
|
|
73427
73940
|
worktreeCommand: () => worktreeCommand
|
|
73428
73941
|
});
|
|
73429
73942
|
import readline4 from "node:readline";
|
|
73430
|
-
import { getProjectRoot as
|
|
73943
|
+
import { getProjectRoot as getProjectRoot57, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
|
|
73431
73944
|
async function promptYesNo2(question) {
|
|
73432
73945
|
return new Promise((resolve11) => {
|
|
73433
73946
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -73532,7 +74045,7 @@ var init_worktree3 = __esm({
|
|
|
73532
74045
|
const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
|
|
73533
74046
|
const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
|
|
73534
74047
|
const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
|
|
73535
|
-
const projectRoot =
|
|
74048
|
+
const projectRoot = getProjectRoot57();
|
|
73536
74049
|
const listResult = await listWorktrees2({
|
|
73537
74050
|
projectRoot,
|
|
73538
74051
|
...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
|
|
@@ -73775,7 +74288,7 @@ init_field_context();
|
|
|
73775
74288
|
init_format_context();
|
|
73776
74289
|
import { readFileSync as readFileSync21 } from "node:fs";
|
|
73777
74290
|
import { dirname as dirname11, join as join37 } from "node:path";
|
|
73778
|
-
import { fileURLToPath as
|
|
74291
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
73779
74292
|
import { enforceNodeVersion } from "@cleocode/paths";
|
|
73780
74293
|
|
|
73781
74294
|
// packages/cleo/src/cli/generated/command-manifest.ts
|
|
@@ -73948,6 +74461,12 @@ var COMMAND_MANIFEST = [
|
|
|
73948
74461
|
description: "Claim a task by assigning it to an agent",
|
|
73949
74462
|
load: async () => (await Promise.resolve().then(() => (init_claim(), claim_exports))).claimCommand
|
|
73950
74463
|
},
|
|
74464
|
+
{
|
|
74465
|
+
exportName: "classifyCommand",
|
|
74466
|
+
name: "classify",
|
|
74467
|
+
description: "Classify a task: readiness verdict (proceed|grill) + persona routing (agent, confidence)",
|
|
74468
|
+
load: async () => (await Promise.resolve().then(() => (init_classify(), classify_exports))).classifyCommand
|
|
74469
|
+
},
|
|
73951
74470
|
{
|
|
73952
74471
|
exportName: "unclaimCommand",
|
|
73953
74472
|
name: "unclaim",
|
|
@@ -74176,10 +74695,16 @@ var COMMAND_MANIFEST = [
|
|
|
74176
74695
|
description: "Transcript garbage collection: manual trigger and status",
|
|
74177
74696
|
load: async () => (await Promise.resolve().then(() => (init_gc(), gc_exports))).gcCommand
|
|
74178
74697
|
},
|
|
74698
|
+
{
|
|
74699
|
+
exportName: "goCommand",
|
|
74700
|
+
name: "go",
|
|
74701
|
+
description: "SG-AUTOPILOT: run one turn of briefing\u2192sagaNext\u2192ready\u2192stage-branch\u2192ivtr loop",
|
|
74702
|
+
load: async () => (await Promise.resolve().then(() => (init_go(), go_exports))).goCommand
|
|
74703
|
+
},
|
|
74179
74704
|
{
|
|
74180
74705
|
exportName: "goalCommand",
|
|
74181
74706
|
name: "goal",
|
|
74182
|
-
description: "DB-persisted, per-agent, evidence-gate-aware goal loop (set/status/subgoal/append).",
|
|
74707
|
+
description: "DB-persisted, per-agent, evidence-gate-aware goal loop (set/status/advance/subgoal/append).",
|
|
74183
74708
|
load: async () => (await Promise.resolve().then(() => (init_goal2(), goal_exports))).goalCommand
|
|
74184
74709
|
},
|
|
74185
74710
|
{
|
|
@@ -74659,7 +75184,7 @@ var COMMAND_MANIFEST = [
|
|
|
74659
75184
|
{
|
|
74660
75185
|
exportName: "workgraphCommand",
|
|
74661
75186
|
name: "workgraph",
|
|
74662
|
-
description: "PM-Core V2 WorkGraph operations \u2014 validate, apply, plan, structure",
|
|
75187
|
+
description: "PM-Core V2 WorkGraph operations \u2014 validate, apply, plan, structure, status",
|
|
74663
75188
|
load: async () => (await Promise.resolve().then(() => (init_workgraph2(), workgraph_exports))).workgraphCommand
|
|
74664
75189
|
},
|
|
74665
75190
|
{
|
|
@@ -74940,7 +75465,7 @@ async function resolveSubCommandForHelp(cmd, rawArgs) {
|
|
|
74940
75465
|
init_summary_context();
|
|
74941
75466
|
enforceNodeVersion();
|
|
74942
75467
|
function getPackageVersion() {
|
|
74943
|
-
const pkgPath = join37(dirname11(
|
|
75468
|
+
const pkgPath = join37(dirname11(fileURLToPath6(import.meta.url)), "../../package.json");
|
|
74944
75469
|
const pkg = JSON.parse(readFileSync21(pkgPath, "utf-8"));
|
|
74945
75470
|
return pkg.version;
|
|
74946
75471
|
}
|
|
@@ -75124,7 +75649,7 @@ async function runStartupMaintenance() {
|
|
|
75124
75649
|
detectAndRemoveStrayProjectNexus,
|
|
75125
75650
|
getGlobalSalt,
|
|
75126
75651
|
getLogger: getLogger20,
|
|
75127
|
-
getProjectRoot:
|
|
75652
|
+
getProjectRoot: getProjectRoot58,
|
|
75128
75653
|
isCleanupMarkerSet,
|
|
75129
75654
|
migrateSignaldockToConduit,
|
|
75130
75655
|
needsSignaldockToConduitMigration,
|
|
@@ -75133,7 +75658,7 @@ async function runStartupMaintenance() {
|
|
|
75133
75658
|
} = await import("@cleocode/core/internal");
|
|
75134
75659
|
let projectRootForCleanup = "";
|
|
75135
75660
|
try {
|
|
75136
|
-
projectRootForCleanup =
|
|
75661
|
+
projectRootForCleanup = getProjectRoot58();
|
|
75137
75662
|
} catch {
|
|
75138
75663
|
}
|
|
75139
75664
|
if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
|
|
@@ -75153,7 +75678,7 @@ async function runStartupMaintenance() {
|
|
|
75153
75678
|
const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
|
|
75154
75679
|
if (!isInitInvocation) {
|
|
75155
75680
|
try {
|
|
75156
|
-
const _projectRootForMigration =
|
|
75681
|
+
const _projectRootForMigration = getProjectRoot58();
|
|
75157
75682
|
if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
|
|
75158
75683
|
const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
|
|
75159
75684
|
if (migrationResult.status === "failed") {
|