@cleocode/cleo 2026.4.152 → 2026.4.154
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 +799 -612
- package/dist/cli/index.js.map +3 -3
- package/package.json +9 -9
package/dist/cli/index.js
CHANGED
|
@@ -385,7 +385,18 @@ var init_branch_lock = __esm({
|
|
|
385
385
|
/** L4c: override requires TTY but stdin/stderr is not a TTY. */
|
|
386
386
|
E_OVERRIDE_NEEDS_TTY: "E_OVERRIDE_NEEDS_TTY",
|
|
387
387
|
/** L4d: session override limit exceeded. */
|
|
388
|
-
E_OVERRIDE_RATE_LIMIT: "E_OVERRIDE_RATE_LIMIT"
|
|
388
|
+
E_OVERRIDE_RATE_LIMIT: "E_OVERRIDE_RATE_LIMIT",
|
|
389
|
+
/**
|
|
390
|
+
* T1501 / P0-5: per-session cap (default 3) exceeded without a valid waiver doc.
|
|
391
|
+
* Set CLEO_OWNER_OVERRIDE_WAIVER=<absolute path> to a file containing
|
|
392
|
+
* `cap-waiver: true` in its frontmatter to bypass the cap.
|
|
393
|
+
*/
|
|
394
|
+
E_OVERRIDE_CAP_EXCEEDED: "E_OVERRIDE_CAP_EXCEEDED",
|
|
395
|
+
/**
|
|
396
|
+
* T1502 / P0-6: the same evidence atom was used across >3 distinct tasks and
|
|
397
|
+
* `--shared-evidence` was not passed (or CLEO_STRICT_EVIDENCE=1 is set in CI).
|
|
398
|
+
*/
|
|
399
|
+
E_SHARED_EVIDENCE_FLAG_REQUIRED: "E_SHARED_EVIDENCE_FLAG_REQUIRED"
|
|
389
400
|
};
|
|
390
401
|
}
|
|
391
402
|
});
|
|
@@ -3772,6 +3783,17 @@ var init_registry = __esm({
|
|
|
3772
3783
|
requiredParams: [],
|
|
3773
3784
|
params: []
|
|
3774
3785
|
},
|
|
3786
|
+
{
|
|
3787
|
+
gateway: "query",
|
|
3788
|
+
domain: "check",
|
|
3789
|
+
operation: "test.coverage",
|
|
3790
|
+
description: "check.test.coverage (query) \u2014 dedicated test coverage sub-op (T1434)",
|
|
3791
|
+
tier: 1,
|
|
3792
|
+
idempotent: true,
|
|
3793
|
+
sessionRequired: false,
|
|
3794
|
+
requiredParams: [],
|
|
3795
|
+
params: []
|
|
3796
|
+
},
|
|
3775
3797
|
{
|
|
3776
3798
|
gateway: "query",
|
|
3777
3799
|
domain: "check",
|
|
@@ -5290,6 +5312,32 @@ var init_registry = __esm({
|
|
|
5290
5312
|
}
|
|
5291
5313
|
]
|
|
5292
5314
|
},
|
|
5315
|
+
// T1147 W7 — sweep mutate variant (approve, rollback) — routes to same handler as query
|
|
5316
|
+
// Registered separately so mutate:memory.sweep resolves correctly (T1496/P0-1)
|
|
5317
|
+
{
|
|
5318
|
+
gateway: "mutate",
|
|
5319
|
+
domain: "memory",
|
|
5320
|
+
operation: "sweep",
|
|
5321
|
+
description: "memory.sweep (mutate) \u2014 T1147 W7 BRAIN noise sweep approve/rollback. approve <runId>: apply sweep to live brain tables. rollback <runId>: discard a staged run without applying changes.",
|
|
5322
|
+
tier: 0,
|
|
5323
|
+
idempotent: false,
|
|
5324
|
+
sessionRequired: false,
|
|
5325
|
+
requiredParams: [],
|
|
5326
|
+
params: [
|
|
5327
|
+
{
|
|
5328
|
+
name: "approve",
|
|
5329
|
+
type: "string",
|
|
5330
|
+
required: false,
|
|
5331
|
+
description: "Run ID to approve and apply to live tables."
|
|
5332
|
+
},
|
|
5333
|
+
{
|
|
5334
|
+
name: "rollback",
|
|
5335
|
+
type: "string",
|
|
5336
|
+
required: false,
|
|
5337
|
+
description: "Run ID to roll back without applying changes."
|
|
5338
|
+
}
|
|
5339
|
+
]
|
|
5340
|
+
},
|
|
5293
5341
|
// T791 — LLM extraction backend status
|
|
5294
5342
|
{
|
|
5295
5343
|
gateway: "query",
|
|
@@ -8563,6 +8611,25 @@ var init_registry = __esm({
|
|
|
8563
8611
|
description: "Remove worktrees idle for longer than this many hours (default: 24)"
|
|
8564
8612
|
}
|
|
8565
8613
|
]
|
|
8614
|
+
},
|
|
8615
|
+
// T1462 — Single-task worktree prune (auto-triggered by cleo complete)
|
|
8616
|
+
{
|
|
8617
|
+
gateway: "mutate",
|
|
8618
|
+
domain: "orchestrate",
|
|
8619
|
+
operation: "worktree.prune",
|
|
8620
|
+
description: "orchestrate.worktree.prune (mutate) \u2014 prune the worktree for a single completed task, or all orphaned worktrees when no taskId is supplied",
|
|
8621
|
+
tier: 2,
|
|
8622
|
+
idempotent: true,
|
|
8623
|
+
sessionRequired: false,
|
|
8624
|
+
requiredParams: [],
|
|
8625
|
+
params: [
|
|
8626
|
+
{
|
|
8627
|
+
name: "taskId",
|
|
8628
|
+
type: "string",
|
|
8629
|
+
required: false,
|
|
8630
|
+
description: "Task ID whose worktree should be pruned (omit for bulk prune)"
|
|
8631
|
+
}
|
|
8632
|
+
]
|
|
8566
8633
|
}
|
|
8567
8634
|
];
|
|
8568
8635
|
counts = getCounts();
|
|
@@ -9584,6 +9651,7 @@ import {
|
|
|
9584
9651
|
paginate,
|
|
9585
9652
|
parseScope,
|
|
9586
9653
|
persistHandoff,
|
|
9654
|
+
readSessionOverrideCount,
|
|
9587
9655
|
recordAssumption,
|
|
9588
9656
|
recordDecision,
|
|
9589
9657
|
showSession,
|
|
@@ -9598,12 +9666,14 @@ async function sessionStatus(projectRoot) {
|
|
|
9598
9666
|
const focusState = await accessor.getMetaValue("focus_state");
|
|
9599
9667
|
const sessions2 = await accessor.loadSessions();
|
|
9600
9668
|
const active = sessions2.find((s) => s.status === "active");
|
|
9669
|
+
const overrideCount = active ? readSessionOverrideCount(projectRoot, active.id) : 0;
|
|
9601
9670
|
return {
|
|
9602
9671
|
success: true,
|
|
9603
9672
|
data: {
|
|
9604
9673
|
hasActiveSession: !!active,
|
|
9605
9674
|
session: active || null,
|
|
9606
|
-
taskWork: focusState || null
|
|
9675
|
+
taskWork: focusState || null,
|
|
9676
|
+
overrideCount
|
|
9607
9677
|
}
|
|
9608
9678
|
};
|
|
9609
9679
|
} catch {
|
|
@@ -14605,8 +14675,10 @@ import {
|
|
|
14605
14675
|
import {
|
|
14606
14676
|
appendForceBypassLine,
|
|
14607
14677
|
appendGateAuditLine,
|
|
14678
|
+
checkAndIncrementOverrideCap,
|
|
14608
14679
|
checkGateEvidenceMinimum,
|
|
14609
14680
|
composeGateEvidence,
|
|
14681
|
+
enforceSharedEvidence,
|
|
14610
14682
|
getAccessor as getAccessor7,
|
|
14611
14683
|
parseEvidence,
|
|
14612
14684
|
validateAtom
|
|
@@ -15111,6 +15183,44 @@ async function validateGateVerify(params, projectRoot) {
|
|
|
15111
15183
|
}
|
|
15112
15184
|
const isWriteRequiringEvidence = (all || gate && value !== false) && !reset;
|
|
15113
15185
|
const override = readOverrideState();
|
|
15186
|
+
let sessionOverrideOrdinal;
|
|
15187
|
+
let isWorktreeCtx = false;
|
|
15188
|
+
if (override.override && isWriteRequiringEvidence) {
|
|
15189
|
+
const command = (process.argv.slice(1).join(" ") || "cleo").slice(0, 512);
|
|
15190
|
+
const capResult = checkAndIncrementOverrideCap(
|
|
15191
|
+
root,
|
|
15192
|
+
sessionId ?? "global",
|
|
15193
|
+
void 0,
|
|
15194
|
+
command
|
|
15195
|
+
);
|
|
15196
|
+
if (!capResult.allowed) {
|
|
15197
|
+
return engineError(
|
|
15198
|
+
capResult.errorCode ?? "E_OVERRIDE_CAP_EXCEEDED",
|
|
15199
|
+
capResult.errorMessage ?? "Per-session override cap exceeded."
|
|
15200
|
+
);
|
|
15201
|
+
}
|
|
15202
|
+
sessionOverrideOrdinal = capResult.sessionOverrideOrdinal;
|
|
15203
|
+
isWorktreeCtx = capResult.workTreeContext === true;
|
|
15204
|
+
}
|
|
15205
|
+
let sharedEvidenceAcknowledged = false;
|
|
15206
|
+
let sharedAtomWarned = false;
|
|
15207
|
+
if (isWriteRequiringEvidence && !override.override && params.evidence && sessionId) {
|
|
15208
|
+
const seResult = enforceSharedEvidence(
|
|
15209
|
+
root,
|
|
15210
|
+
sessionId,
|
|
15211
|
+
taskId,
|
|
15212
|
+
params.evidence,
|
|
15213
|
+
params.sharedEvidence === true
|
|
15214
|
+
);
|
|
15215
|
+
if (!seResult.allowed) {
|
|
15216
|
+
return engineError(
|
|
15217
|
+
seResult.errorCode ?? "E_SHARED_EVIDENCE_FLAG_REQUIRED",
|
|
15218
|
+
seResult.errorMessage ?? "Shared evidence flag required."
|
|
15219
|
+
);
|
|
15220
|
+
}
|
|
15221
|
+
sharedEvidenceAcknowledged = seResult.acknowledged === true;
|
|
15222
|
+
sharedAtomWarned = seResult.warned === true;
|
|
15223
|
+
}
|
|
15114
15224
|
let verification = task.verification ?? initVerification();
|
|
15115
15225
|
if (!verification.evidence) {
|
|
15116
15226
|
verification.evidence = {};
|
|
@@ -15225,7 +15335,18 @@ Or set CLEO_OWNER_OVERRIDE=1 with CLEO_OWNER_OVERRIDE_REASON=<reason> for emerge
|
|
|
15225
15335
|
...auditRecord,
|
|
15226
15336
|
overrideReason: override.reason,
|
|
15227
15337
|
pid: process.pid,
|
|
15228
|
-
command: (process.argv.slice(1).join(" ") || "cleo").slice(0, 512)
|
|
15338
|
+
command: (process.argv.slice(1).join(" ") || "cleo").slice(0, 512),
|
|
15339
|
+
...sessionOverrideOrdinal !== void 0 ? { sessionOverrideOrdinal } : {},
|
|
15340
|
+
...isWorktreeCtx ? { workTreeContext: true } : {}
|
|
15341
|
+
});
|
|
15342
|
+
} else if ((sharedEvidenceAcknowledged || sharedAtomWarned) && action !== "reset") {
|
|
15343
|
+
await appendForceBypassLine(root, {
|
|
15344
|
+
...auditRecord,
|
|
15345
|
+
overrideReason: "shared-evidence",
|
|
15346
|
+
pid: process.pid,
|
|
15347
|
+
command: (process.argv.slice(1).join(" ") || "cleo").slice(0, 512),
|
|
15348
|
+
...sharedEvidenceAcknowledged ? { sharedEvidence: true } : {},
|
|
15349
|
+
...sharedAtomWarned ? { sharedAtomWarning: true } : {}
|
|
15229
15350
|
});
|
|
15230
15351
|
}
|
|
15231
15352
|
} catch {
|
|
@@ -17729,7 +17850,8 @@ var init_check = __esm({
|
|
|
17729
17850
|
all: params.all,
|
|
17730
17851
|
reset: params.reset,
|
|
17731
17852
|
evidence: params.evidence,
|
|
17732
|
-
sessionId: params.sessionId
|
|
17853
|
+
sessionId: params.sessionId,
|
|
17854
|
+
sharedEvidence: params.sharedEvidence
|
|
17733
17855
|
};
|
|
17734
17856
|
const result = await validateGateVerify(gateParams, projectRoot);
|
|
17735
17857
|
setImmediate(async () => {
|
|
@@ -17818,6 +17940,7 @@ var init_check = __esm({
|
|
|
17818
17940
|
"compliance.summary",
|
|
17819
17941
|
"workflow.compliance",
|
|
17820
17942
|
"test",
|
|
17943
|
+
"test.coverage",
|
|
17821
17944
|
"coherence",
|
|
17822
17945
|
"gate.status",
|
|
17823
17946
|
"archive.stats",
|
|
@@ -18590,197 +18713,375 @@ function mimeFromPath(filePath) {
|
|
|
18590
18713
|
if (lower.endsWith(".css")) return "text/css";
|
|
18591
18714
|
return "application/octet-stream";
|
|
18592
18715
|
}
|
|
18593
|
-
|
|
18716
|
+
function docsEnvelopeToResponse(envelope, gateway, operation, startTime) {
|
|
18717
|
+
if (!envelope.success) {
|
|
18718
|
+
return {
|
|
18719
|
+
meta: dispatchMeta(gateway, "docs", operation, startTime),
|
|
18720
|
+
success: false,
|
|
18721
|
+
error: {
|
|
18722
|
+
code: String(envelope.error?.code ?? "E_INTERNAL"),
|
|
18723
|
+
message: envelope.error?.message ?? "Unknown error"
|
|
18724
|
+
}
|
|
18725
|
+
};
|
|
18726
|
+
}
|
|
18727
|
+
let attachmentBackend;
|
|
18728
|
+
let responseData = envelope.data;
|
|
18729
|
+
if (responseData !== null && responseData !== void 0 && typeof responseData === "object") {
|
|
18730
|
+
const dataObj = responseData;
|
|
18731
|
+
if ("attachmentBackend" in dataObj && dataObj["attachmentBackend"] !== void 0) {
|
|
18732
|
+
attachmentBackend = dataObj["attachmentBackend"];
|
|
18733
|
+
const { attachmentBackend: _lifted, ...cleanData } = dataObj;
|
|
18734
|
+
responseData = cleanData;
|
|
18735
|
+
}
|
|
18736
|
+
}
|
|
18737
|
+
return {
|
|
18738
|
+
meta: {
|
|
18739
|
+
...dispatchMeta(gateway, "docs", operation, startTime),
|
|
18740
|
+
...attachmentBackend !== void 0 ? { attachmentBackend } : {}
|
|
18741
|
+
},
|
|
18742
|
+
success: true,
|
|
18743
|
+
data: responseData
|
|
18744
|
+
};
|
|
18745
|
+
}
|
|
18746
|
+
var _docsTypedHandler, QUERY_OPS3, MUTATE_OPS3, DocsHandler;
|
|
18594
18747
|
var init_docs = __esm({
|
|
18595
18748
|
"packages/cleo/src/dispatch/domains/docs.ts"() {
|
|
18596
18749
|
"use strict";
|
|
18750
|
+
init_typed();
|
|
18597
18751
|
init_base();
|
|
18598
18752
|
init_meta2();
|
|
18753
|
+
_docsTypedHandler = defineTypedHandler("docs", {
|
|
18754
|
+
// ── docs.list ──────────────────────────────────────────────────────────────
|
|
18755
|
+
list: async (params) => {
|
|
18756
|
+
const ownerId = params.task ?? params.session ?? params.observation;
|
|
18757
|
+
if (!ownerId) {
|
|
18758
|
+
return lafsError(
|
|
18759
|
+
"E_INVALID_INPUT",
|
|
18760
|
+
"Provide one of --task, --session, or --observation to scope the list.",
|
|
18761
|
+
"list"
|
|
18762
|
+
);
|
|
18763
|
+
}
|
|
18764
|
+
const ownerType = inferOwnerType(ownerId);
|
|
18765
|
+
const store = createAttachmentStore();
|
|
18766
|
+
const attachments = await store.listByOwner(ownerType, ownerId);
|
|
18767
|
+
const backend = await resolveAttachmentBackend();
|
|
18768
|
+
return lafsSuccess(
|
|
18769
|
+
{
|
|
18770
|
+
ownerId,
|
|
18771
|
+
ownerType,
|
|
18772
|
+
count: attachments.length,
|
|
18773
|
+
attachments: attachments.map((m) => ({
|
|
18774
|
+
id: m.id,
|
|
18775
|
+
sha256: `${m.sha256.slice(0, 8)}\u2026`,
|
|
18776
|
+
// Cast: contracts AttachmentKind doesn't include 'llmtxt-doc' (contracts gap T1529)
|
|
18777
|
+
kind: m.attachment.kind,
|
|
18778
|
+
mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
|
|
18779
|
+
size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
|
|
18780
|
+
description: m.attachment.description,
|
|
18781
|
+
labels: m.attachment.labels,
|
|
18782
|
+
createdAt: m.createdAt,
|
|
18783
|
+
refCount: m.refCount
|
|
18784
|
+
})),
|
|
18785
|
+
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (drift T1529)
|
|
18786
|
+
attachmentBackend: backend
|
|
18787
|
+
},
|
|
18788
|
+
"list"
|
|
18789
|
+
);
|
|
18790
|
+
},
|
|
18791
|
+
// ── docs.generate ──────────────────────────────────────────────────────────
|
|
18792
|
+
generate: async (params) => {
|
|
18793
|
+
const forId = params.for;
|
|
18794
|
+
if (!forId) {
|
|
18795
|
+
return lafsError("E_INVALID_INPUT", "--for <taskId|epicId> is required", "generate");
|
|
18796
|
+
}
|
|
18797
|
+
const cwd = getProjectRoot4();
|
|
18798
|
+
const result = await generateDocsLlmsTxt({ ownerId: forId, cwd });
|
|
18799
|
+
let attachmentId;
|
|
18800
|
+
let attachmentSha256;
|
|
18801
|
+
if (params.attach) {
|
|
18802
|
+
const store = createAttachmentStore();
|
|
18803
|
+
const ownerType = inferOwnerType(forId);
|
|
18804
|
+
const contentBytes = Buffer.from(result.content, "utf-8");
|
|
18805
|
+
const llmsTxtDescriptor = {
|
|
18806
|
+
kind: "llms-txt",
|
|
18807
|
+
source: "generated",
|
|
18808
|
+
content: result.content,
|
|
18809
|
+
description: `llms.txt for ${forId} (${result.attachmentCount} docs)`,
|
|
18810
|
+
labels: ["llms-txt", "generated"]
|
|
18811
|
+
};
|
|
18812
|
+
const meta = await store.put(
|
|
18813
|
+
contentBytes,
|
|
18814
|
+
llmsTxtDescriptor,
|
|
18815
|
+
ownerType,
|
|
18816
|
+
forId,
|
|
18817
|
+
"cleo-docs-generate",
|
|
18818
|
+
cwd
|
|
18819
|
+
);
|
|
18820
|
+
attachmentId = meta.id;
|
|
18821
|
+
attachmentSha256 = meta.sha256;
|
|
18822
|
+
}
|
|
18823
|
+
return lafsSuccess(
|
|
18824
|
+
{
|
|
18825
|
+
forId,
|
|
18826
|
+
content: result.content,
|
|
18827
|
+
attachmentCount: result.attachmentCount,
|
|
18828
|
+
usedLlmtxtPackage: result.usedLlmtxtPackage,
|
|
18829
|
+
...attachmentId !== void 0 ? {
|
|
18830
|
+
attached: true,
|
|
18831
|
+
attachmentId,
|
|
18832
|
+
attachmentSha256
|
|
18833
|
+
} : { attached: false }
|
|
18834
|
+
},
|
|
18835
|
+
"generate"
|
|
18836
|
+
);
|
|
18837
|
+
},
|
|
18838
|
+
// ── docs.fetch ─────────────────────────────────────────────────────────────
|
|
18839
|
+
fetch: async (params) => {
|
|
18840
|
+
const ref = params.attachmentRef;
|
|
18841
|
+
if (!ref) {
|
|
18842
|
+
return lafsError(
|
|
18843
|
+
"E_INVALID_INPUT",
|
|
18844
|
+
"attachmentRef is required (attachment ID or SHA-256 hex)",
|
|
18845
|
+
"fetch"
|
|
18846
|
+
);
|
|
18847
|
+
}
|
|
18848
|
+
const store = createAttachmentStore();
|
|
18849
|
+
const isSha256 = /^[0-9a-f]{64}$/i.test(ref);
|
|
18850
|
+
let fetchResult = null;
|
|
18851
|
+
let metadata = await store.getMetadata(ref);
|
|
18852
|
+
if (metadata) {
|
|
18853
|
+
fetchResult = await store.get(metadata.sha256);
|
|
18854
|
+
} else if (isSha256) {
|
|
18855
|
+
fetchResult = await store.get(ref);
|
|
18856
|
+
if (fetchResult) {
|
|
18857
|
+
metadata = fetchResult.metadata;
|
|
18858
|
+
}
|
|
18859
|
+
}
|
|
18860
|
+
if (!fetchResult || !metadata) {
|
|
18861
|
+
return lafsError("E_NOT_FOUND", `Attachment not found: ${ref}`, "fetch");
|
|
18862
|
+
}
|
|
18863
|
+
const cwd = getProjectRoot4();
|
|
18864
|
+
const cleoDir = getCleoDirAbsolute(cwd);
|
|
18865
|
+
let storagePath;
|
|
18866
|
+
if (metadata.attachment.kind === "local-file") {
|
|
18867
|
+
storagePath = metadata.attachment.path;
|
|
18868
|
+
} else if (metadata.attachment.kind === "blob") {
|
|
18869
|
+
const prefix = metadata.sha256.slice(0, 2);
|
|
18870
|
+
const rest = metadata.sha256.slice(2);
|
|
18871
|
+
const extMap = {
|
|
18872
|
+
"text/markdown": ".md",
|
|
18873
|
+
"text/plain": ".txt",
|
|
18874
|
+
"application/json": ".json",
|
|
18875
|
+
"application/pdf": ".pdf"
|
|
18876
|
+
};
|
|
18877
|
+
const mime = metadata.attachment.kind === "blob" ? metadata.attachment.mime : "application/octet-stream";
|
|
18878
|
+
const ext = extMap[mime] ?? ".bin";
|
|
18879
|
+
storagePath = resolve2(cleoDir, "attachments", "sha256", prefix, `${rest}${ext}`);
|
|
18880
|
+
}
|
|
18881
|
+
const MAX_INLINE = 1024 * 1024;
|
|
18882
|
+
const bytesBase64 = fetchResult.bytes.length <= MAX_INLINE ? fetchResult.bytes.toString("base64") : void 0;
|
|
18883
|
+
const backend = await resolveAttachmentBackend();
|
|
18884
|
+
return lafsSuccess(
|
|
18885
|
+
{
|
|
18886
|
+
// Cast: core's AttachmentMetadata vs contracts/operations/docs AttachmentMetadata differ
|
|
18887
|
+
// in their nested attachment field structure (T1529 contracts gap). The runtime
|
|
18888
|
+
// value is compatible for all callers; the two interfaces diverged at the type level.
|
|
18889
|
+
metadata,
|
|
18890
|
+
path: storagePath,
|
|
18891
|
+
sizeBytes: fetchResult.bytes.length,
|
|
18892
|
+
...bytesBase64 !== void 0 ? { bytesBase64 } : {},
|
|
18893
|
+
inlined: bytesBase64 !== void 0,
|
|
18894
|
+
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
|
|
18895
|
+
attachmentBackend: backend
|
|
18896
|
+
},
|
|
18897
|
+
"fetch"
|
|
18898
|
+
);
|
|
18899
|
+
},
|
|
18900
|
+
// ── docs.add ───────────────────────────────────────────────────────────────
|
|
18901
|
+
add: async (params) => {
|
|
18902
|
+
const {
|
|
18903
|
+
ownerId,
|
|
18904
|
+
file: filePath,
|
|
18905
|
+
url,
|
|
18906
|
+
desc: description,
|
|
18907
|
+
labels: rawLabels,
|
|
18908
|
+
attachedBy: rawAttachedBy
|
|
18909
|
+
} = params;
|
|
18910
|
+
if (!ownerId) {
|
|
18911
|
+
return lafsError("E_INVALID_INPUT", "ownerId is required", "add");
|
|
18912
|
+
}
|
|
18913
|
+
if (!filePath && !url) {
|
|
18914
|
+
return lafsError(
|
|
18915
|
+
"E_INVALID_INPUT",
|
|
18916
|
+
"Provide either a file path (positional or --file) or --url",
|
|
18917
|
+
"add"
|
|
18918
|
+
);
|
|
18919
|
+
}
|
|
18920
|
+
const labels = parseLabels(rawLabels);
|
|
18921
|
+
const attachedBy = rawAttachedBy ?? "human";
|
|
18922
|
+
const ownerType = inferOwnerType(ownerId);
|
|
18923
|
+
const store = createAttachmentStore();
|
|
18924
|
+
if (filePath) {
|
|
18925
|
+
const absPath = resolve2(filePath);
|
|
18926
|
+
let bytes;
|
|
18927
|
+
try {
|
|
18928
|
+
bytes = await readFile(absPath);
|
|
18929
|
+
} catch {
|
|
18930
|
+
return lafsError("E_FILE_ERROR", `Cannot read file: ${absPath}`, "add");
|
|
18931
|
+
}
|
|
18932
|
+
const mime = mimeFromPath(absPath);
|
|
18933
|
+
const attachment = {
|
|
18934
|
+
kind: "local-file",
|
|
18935
|
+
path: absPath,
|
|
18936
|
+
mime,
|
|
18937
|
+
size: bytes.length,
|
|
18938
|
+
...description ? { description } : {},
|
|
18939
|
+
...labels ? { labels } : {}
|
|
18940
|
+
};
|
|
18941
|
+
const meta = await store.put(bytes, attachment, ownerType, ownerId, attachedBy);
|
|
18942
|
+
let backend = "legacy";
|
|
18943
|
+
try {
|
|
18944
|
+
const v2 = createAttachmentStoreV2(getProjectRoot4());
|
|
18945
|
+
const v2Result = await v2.put(ownerId, {
|
|
18946
|
+
name: absPath.split(/[\\/]/).pop() ?? meta.sha256.slice(0, 12),
|
|
18947
|
+
data: new Uint8Array(bytes),
|
|
18948
|
+
contentType: mime
|
|
18949
|
+
});
|
|
18950
|
+
backend = v2Result.backend;
|
|
18951
|
+
} catch {
|
|
18952
|
+
backend = await resolveAttachmentBackend();
|
|
18953
|
+
}
|
|
18954
|
+
import("@cleocode/core/internal").then(
|
|
18955
|
+
({ ensureLlmtxtNode }) => ensureLlmtxtNode(
|
|
18956
|
+
getProjectRoot4(),
|
|
18957
|
+
meta.sha256,
|
|
18958
|
+
`${ownerType}:${ownerId}`,
|
|
18959
|
+
absPath.split("/").pop() ?? meta.sha256.slice(0, 12)
|
|
18960
|
+
)
|
|
18961
|
+
).catch(() => {
|
|
18962
|
+
});
|
|
18963
|
+
return lafsSuccess(
|
|
18964
|
+
{
|
|
18965
|
+
attachmentId: meta.id,
|
|
18966
|
+
sha256: meta.sha256,
|
|
18967
|
+
refCount: meta.refCount,
|
|
18968
|
+
kind: "local-file",
|
|
18969
|
+
ownerId,
|
|
18970
|
+
ownerType,
|
|
18971
|
+
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
|
|
18972
|
+
attachmentBackend: backend
|
|
18973
|
+
},
|
|
18974
|
+
"add"
|
|
18975
|
+
);
|
|
18976
|
+
}
|
|
18977
|
+
if (url) {
|
|
18978
|
+
const attachment = {
|
|
18979
|
+
kind: "url",
|
|
18980
|
+
url,
|
|
18981
|
+
...description ? { description } : {},
|
|
18982
|
+
...labels ? { labels } : {}
|
|
18983
|
+
};
|
|
18984
|
+
const urlBytes = Buffer.from(url, "utf-8");
|
|
18985
|
+
const meta = await store.put(urlBytes, attachment, ownerType, ownerId, attachedBy);
|
|
18986
|
+
import("@cleocode/core/internal").then(
|
|
18987
|
+
({ ensureLlmtxtNode }) => ensureLlmtxtNode(getProjectRoot4(), meta.sha256, `${ownerType}:${ownerId}`, url)
|
|
18988
|
+
).catch(() => {
|
|
18989
|
+
});
|
|
18990
|
+
const backend = "legacy";
|
|
18991
|
+
return lafsSuccess(
|
|
18992
|
+
{
|
|
18993
|
+
attachmentId: meta.id,
|
|
18994
|
+
sha256: meta.sha256,
|
|
18995
|
+
refCount: meta.refCount,
|
|
18996
|
+
kind: "url",
|
|
18997
|
+
url,
|
|
18998
|
+
ownerId,
|
|
18999
|
+
ownerType,
|
|
19000
|
+
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
|
|
19001
|
+
attachmentBackend: backend
|
|
19002
|
+
},
|
|
19003
|
+
"add"
|
|
19004
|
+
);
|
|
19005
|
+
}
|
|
19006
|
+
return lafsError("E_INVALID_INPUT", "Unreachable: no file or url", "add");
|
|
19007
|
+
},
|
|
19008
|
+
// ── docs.remove ────────────────────────────────────────────────────────────
|
|
19009
|
+
remove: async (params) => {
|
|
19010
|
+
const { attachmentRef: ref, from: fromOwner } = params;
|
|
19011
|
+
if (!ref) {
|
|
19012
|
+
return lafsError(
|
|
19013
|
+
"E_INVALID_INPUT",
|
|
19014
|
+
"attachmentRef is required (attachment ID or SHA-256 hex)",
|
|
19015
|
+
"remove"
|
|
19016
|
+
);
|
|
19017
|
+
}
|
|
19018
|
+
if (!fromOwner) {
|
|
19019
|
+
return lafsError("E_INVALID_INPUT", "--from <ownerId> is required", "remove");
|
|
19020
|
+
}
|
|
19021
|
+
const store = createAttachmentStore();
|
|
19022
|
+
const ownerType = inferOwnerType(fromOwner);
|
|
19023
|
+
let attachmentId = ref;
|
|
19024
|
+
if (/^[0-9a-f]{64}$/i.test(ref)) {
|
|
19025
|
+
const result = await store.get(ref);
|
|
19026
|
+
if (!result) {
|
|
19027
|
+
return lafsError("E_NOT_FOUND", `No attachment found with SHA-256: ${ref}`, "remove");
|
|
19028
|
+
}
|
|
19029
|
+
attachmentId = result.metadata.id;
|
|
19030
|
+
}
|
|
19031
|
+
const derefResult = await store.deref(attachmentId, ownerType, fromOwner);
|
|
19032
|
+
if (derefResult.status === "not-found") {
|
|
19033
|
+
return lafsError(
|
|
19034
|
+
"E_NOT_FOUND",
|
|
19035
|
+
`Attachment ref not found: ${attachmentId} on owner ${fromOwner}`,
|
|
19036
|
+
"remove"
|
|
19037
|
+
);
|
|
19038
|
+
}
|
|
19039
|
+
const blobPurged = derefResult.status === "removed";
|
|
19040
|
+
const refCountAfter = derefResult.status === "derefd" ? derefResult.refCountAfter : 0;
|
|
19041
|
+
try {
|
|
19042
|
+
const v2 = createAttachmentStoreV2(getProjectRoot4());
|
|
19043
|
+
await v2.remove(attachmentId, fromOwner);
|
|
19044
|
+
} catch {
|
|
19045
|
+
}
|
|
19046
|
+
const backend = await resolveAttachmentBackend();
|
|
19047
|
+
return lafsSuccess(
|
|
19048
|
+
{
|
|
19049
|
+
removed: blobPurged,
|
|
19050
|
+
attachmentId,
|
|
19051
|
+
from: fromOwner,
|
|
19052
|
+
refCountAfter,
|
|
19053
|
+
blobPurged,
|
|
19054
|
+
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
|
|
19055
|
+
attachmentBackend: backend
|
|
19056
|
+
},
|
|
19057
|
+
"remove"
|
|
19058
|
+
);
|
|
19059
|
+
}
|
|
19060
|
+
});
|
|
19061
|
+
QUERY_OPS3 = /* @__PURE__ */ new Set(["list", "fetch", "generate"]);
|
|
19062
|
+
MUTATE_OPS3 = /* @__PURE__ */ new Set(["add", "remove"]);
|
|
18599
19063
|
DocsHandler = class {
|
|
18600
19064
|
// -----------------------------------------------------------------------
|
|
18601
19065
|
// Query
|
|
18602
19066
|
// -----------------------------------------------------------------------
|
|
19067
|
+
/**
|
|
19068
|
+
* Execute a read-only docs query operation.
|
|
19069
|
+
*
|
|
19070
|
+
* @param operation - The docs query op name (e.g. 'list', 'fetch', 'generate').
|
|
19071
|
+
* @param params - Raw params from the dispatcher (narrowed internally).
|
|
19072
|
+
*/
|
|
18603
19073
|
async query(operation, params) {
|
|
18604
19074
|
const startTime = Date.now();
|
|
19075
|
+
if (!QUERY_OPS3.has(operation)) {
|
|
19076
|
+
return unsupportedOp("query", "docs", operation, startTime);
|
|
19077
|
+
}
|
|
18605
19078
|
try {
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
const ownerId = taskId ?? sessionId ?? observationId;
|
|
18613
|
-
if (!ownerId) {
|
|
18614
|
-
return errorResult(
|
|
18615
|
-
"query",
|
|
18616
|
-
"docs",
|
|
18617
|
-
operation,
|
|
18618
|
-
"E_INVALID_INPUT",
|
|
18619
|
-
"Provide one of --task, --session, or --observation to scope the list.",
|
|
18620
|
-
startTime
|
|
18621
|
-
);
|
|
18622
|
-
}
|
|
18623
|
-
const ownerType = inferOwnerType(ownerId);
|
|
18624
|
-
const store = createAttachmentStore();
|
|
18625
|
-
const attachments = await store.listByOwner(ownerType, ownerId);
|
|
18626
|
-
const backend = await resolveAttachmentBackend();
|
|
18627
|
-
return {
|
|
18628
|
-
meta: {
|
|
18629
|
-
...dispatchMeta("query", "docs", operation, startTime),
|
|
18630
|
-
attachmentBackend: backend
|
|
18631
|
-
},
|
|
18632
|
-
success: true,
|
|
18633
|
-
data: {
|
|
18634
|
-
ownerId,
|
|
18635
|
-
ownerType,
|
|
18636
|
-
count: attachments.length,
|
|
18637
|
-
attachments: attachments.map((m) => ({
|
|
18638
|
-
id: m.id,
|
|
18639
|
-
sha256: `${m.sha256.slice(0, 8)}\u2026`,
|
|
18640
|
-
kind: m.attachment.kind,
|
|
18641
|
-
mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
|
|
18642
|
-
size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
|
|
18643
|
-
description: m.attachment.description,
|
|
18644
|
-
labels: m.attachment.labels,
|
|
18645
|
-
createdAt: m.createdAt,
|
|
18646
|
-
refCount: m.refCount
|
|
18647
|
-
}))
|
|
18648
|
-
}
|
|
18649
|
-
};
|
|
18650
|
-
}
|
|
18651
|
-
// ── docs.generate ────────────────────────────────────────────────
|
|
18652
|
-
case "generate": {
|
|
18653
|
-
const forId = params?.for;
|
|
18654
|
-
if (!forId) {
|
|
18655
|
-
return errorResult(
|
|
18656
|
-
"query",
|
|
18657
|
-
"docs",
|
|
18658
|
-
operation,
|
|
18659
|
-
"E_INVALID_INPUT",
|
|
18660
|
-
"--for <taskId|epicId> is required",
|
|
18661
|
-
startTime
|
|
18662
|
-
);
|
|
18663
|
-
}
|
|
18664
|
-
const attach = params?.attach;
|
|
18665
|
-
const cwd = getProjectRoot4();
|
|
18666
|
-
const result = await generateDocsLlmsTxt({
|
|
18667
|
-
ownerId: forId,
|
|
18668
|
-
cwd
|
|
18669
|
-
});
|
|
18670
|
-
let attachmentId;
|
|
18671
|
-
let attachmentSha256;
|
|
18672
|
-
if (attach) {
|
|
18673
|
-
const store = createAttachmentStore();
|
|
18674
|
-
const ownerType = inferOwnerType(forId);
|
|
18675
|
-
const contentBytes = Buffer.from(result.content, "utf-8");
|
|
18676
|
-
const llmsTxtDescriptor = {
|
|
18677
|
-
kind: "llms-txt",
|
|
18678
|
-
source: "generated",
|
|
18679
|
-
content: result.content,
|
|
18680
|
-
description: `llms.txt for ${forId} (${result.attachmentCount} docs)`,
|
|
18681
|
-
labels: ["llms-txt", "generated"]
|
|
18682
|
-
};
|
|
18683
|
-
const meta = await store.put(
|
|
18684
|
-
contentBytes,
|
|
18685
|
-
llmsTxtDescriptor,
|
|
18686
|
-
ownerType,
|
|
18687
|
-
forId,
|
|
18688
|
-
"cleo-docs-generate",
|
|
18689
|
-
cwd
|
|
18690
|
-
);
|
|
18691
|
-
attachmentId = meta.id;
|
|
18692
|
-
attachmentSha256 = meta.sha256;
|
|
18693
|
-
}
|
|
18694
|
-
return {
|
|
18695
|
-
meta: dispatchMeta("query", "docs", operation, startTime),
|
|
18696
|
-
success: true,
|
|
18697
|
-
data: {
|
|
18698
|
-
forId,
|
|
18699
|
-
content: result.content,
|
|
18700
|
-
attachmentCount: result.attachmentCount,
|
|
18701
|
-
usedLlmtxtPackage: result.usedLlmtxtPackage,
|
|
18702
|
-
...attachmentId !== void 0 ? {
|
|
18703
|
-
attached: true,
|
|
18704
|
-
attachmentId,
|
|
18705
|
-
attachmentSha256
|
|
18706
|
-
} : { attached: false }
|
|
18707
|
-
}
|
|
18708
|
-
};
|
|
18709
|
-
}
|
|
18710
|
-
// ── docs.fetch ───────────────────────────────────────────────────
|
|
18711
|
-
case "fetch": {
|
|
18712
|
-
const ref = params?.attachmentRef;
|
|
18713
|
-
if (!ref) {
|
|
18714
|
-
return errorResult(
|
|
18715
|
-
"query",
|
|
18716
|
-
"docs",
|
|
18717
|
-
operation,
|
|
18718
|
-
"E_INVALID_INPUT",
|
|
18719
|
-
"attachmentRef is required (attachment ID or SHA-256 hex)",
|
|
18720
|
-
startTime
|
|
18721
|
-
);
|
|
18722
|
-
}
|
|
18723
|
-
const store = createAttachmentStore();
|
|
18724
|
-
const isSha256 = /^[0-9a-f]{64}$/i.test(ref);
|
|
18725
|
-
let result = null;
|
|
18726
|
-
let metadata = await store.getMetadata(ref);
|
|
18727
|
-
if (metadata) {
|
|
18728
|
-
result = await store.get(metadata.sha256);
|
|
18729
|
-
} else if (isSha256) {
|
|
18730
|
-
result = await store.get(ref);
|
|
18731
|
-
if (result) {
|
|
18732
|
-
metadata = result.metadata;
|
|
18733
|
-
}
|
|
18734
|
-
}
|
|
18735
|
-
if (!result || !metadata) {
|
|
18736
|
-
return errorResult(
|
|
18737
|
-
"query",
|
|
18738
|
-
"docs",
|
|
18739
|
-
operation,
|
|
18740
|
-
"E_NOT_FOUND",
|
|
18741
|
-
`Attachment not found: ${ref}`,
|
|
18742
|
-
startTime
|
|
18743
|
-
);
|
|
18744
|
-
}
|
|
18745
|
-
const cwd = getProjectRoot4();
|
|
18746
|
-
const cleoDir = getCleoDirAbsolute(cwd);
|
|
18747
|
-
let storagePath;
|
|
18748
|
-
if (metadata.attachment.kind === "local-file") {
|
|
18749
|
-
storagePath = metadata.attachment.path;
|
|
18750
|
-
} else if (metadata.attachment.kind === "blob") {
|
|
18751
|
-
const prefix = metadata.sha256.slice(0, 2);
|
|
18752
|
-
const rest = metadata.sha256.slice(2);
|
|
18753
|
-
const extMap = {
|
|
18754
|
-
"text/markdown": ".md",
|
|
18755
|
-
"text/plain": ".txt",
|
|
18756
|
-
"application/json": ".json",
|
|
18757
|
-
"application/pdf": ".pdf"
|
|
18758
|
-
};
|
|
18759
|
-
const mime = metadata.attachment.kind === "blob" ? metadata.attachment.mime : "application/octet-stream";
|
|
18760
|
-
const ext = extMap[mime] ?? ".bin";
|
|
18761
|
-
storagePath = resolve2(cleoDir, "attachments", "sha256", prefix, `${rest}${ext}`);
|
|
18762
|
-
}
|
|
18763
|
-
const MAX_INLINE = 1024 * 1024;
|
|
18764
|
-
const bytesBase64 = result.bytes.length <= MAX_INLINE ? result.bytes.toString("base64") : void 0;
|
|
18765
|
-
const backend = await resolveAttachmentBackend();
|
|
18766
|
-
return {
|
|
18767
|
-
meta: {
|
|
18768
|
-
...dispatchMeta("query", "docs", operation, startTime),
|
|
18769
|
-
attachmentBackend: backend
|
|
18770
|
-
},
|
|
18771
|
-
success: true,
|
|
18772
|
-
data: {
|
|
18773
|
-
metadata,
|
|
18774
|
-
path: storagePath,
|
|
18775
|
-
sizeBytes: result.bytes.length,
|
|
18776
|
-
...bytesBase64 !== void 0 ? { bytesBase64 } : {},
|
|
18777
|
-
inlined: bytesBase64 !== void 0
|
|
18778
|
-
}
|
|
18779
|
-
};
|
|
18780
|
-
}
|
|
18781
|
-
default:
|
|
18782
|
-
return unsupportedOp("query", "docs", operation, startTime);
|
|
18783
|
-
}
|
|
19079
|
+
const envelope = await typedDispatch(
|
|
19080
|
+
_docsTypedHandler,
|
|
19081
|
+
operation,
|
|
19082
|
+
params ?? {}
|
|
19083
|
+
);
|
|
19084
|
+
return docsEnvelopeToResponse(envelope, "query", operation, startTime);
|
|
18784
19085
|
} catch (error) {
|
|
18785
19086
|
return handleErrorResult("query", "docs", operation, error, startTime);
|
|
18786
19087
|
}
|
|
@@ -18788,220 +19089,24 @@ var init_docs = __esm({
|
|
|
18788
19089
|
// -----------------------------------------------------------------------
|
|
18789
19090
|
// Mutate
|
|
18790
19091
|
// -----------------------------------------------------------------------
|
|
19092
|
+
/**
|
|
19093
|
+
* Execute a state-modifying docs mutation operation.
|
|
19094
|
+
*
|
|
19095
|
+
* @param operation - The docs mutate op name (e.g. 'add', 'remove').
|
|
19096
|
+
* @param params - Raw params from the dispatcher (narrowed internally).
|
|
19097
|
+
*/
|
|
18791
19098
|
async mutate(operation, params) {
|
|
18792
19099
|
const startTime = Date.now();
|
|
19100
|
+
if (!MUTATE_OPS3.has(operation)) {
|
|
19101
|
+
return unsupportedOp("mutate", "docs", operation, startTime);
|
|
19102
|
+
}
|
|
18793
19103
|
try {
|
|
18794
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
18800
|
-
"mutate",
|
|
18801
|
-
"docs",
|
|
18802
|
-
operation,
|
|
18803
|
-
"E_INVALID_INPUT",
|
|
18804
|
-
"ownerId is required",
|
|
18805
|
-
startTime
|
|
18806
|
-
);
|
|
18807
|
-
}
|
|
18808
|
-
const filePath = params?.file;
|
|
18809
|
-
const url = params?.url;
|
|
18810
|
-
if (!filePath && !url) {
|
|
18811
|
-
return errorResult(
|
|
18812
|
-
"mutate",
|
|
18813
|
-
"docs",
|
|
18814
|
-
operation,
|
|
18815
|
-
"E_INVALID_INPUT",
|
|
18816
|
-
"Provide either a file path (positional or --file) or --url",
|
|
18817
|
-
startTime
|
|
18818
|
-
);
|
|
18819
|
-
}
|
|
18820
|
-
const description = params?.desc;
|
|
18821
|
-
const labels = parseLabels(params?.labels);
|
|
18822
|
-
const attachedBy = params?.attachedBy ?? "human";
|
|
18823
|
-
const ownerType = inferOwnerType(ownerId);
|
|
18824
|
-
const store = createAttachmentStore();
|
|
18825
|
-
if (filePath) {
|
|
18826
|
-
const absPath = resolve2(filePath);
|
|
18827
|
-
let bytes;
|
|
18828
|
-
try {
|
|
18829
|
-
bytes = await readFile(absPath);
|
|
18830
|
-
} catch {
|
|
18831
|
-
return errorResult(
|
|
18832
|
-
"mutate",
|
|
18833
|
-
"docs",
|
|
18834
|
-
operation,
|
|
18835
|
-
"E_FILE_ERROR",
|
|
18836
|
-
`Cannot read file: ${absPath}`,
|
|
18837
|
-
startTime
|
|
18838
|
-
);
|
|
18839
|
-
}
|
|
18840
|
-
const mime = mimeFromPath(absPath);
|
|
18841
|
-
const attachment = {
|
|
18842
|
-
kind: "local-file",
|
|
18843
|
-
path: absPath,
|
|
18844
|
-
mime,
|
|
18845
|
-
size: bytes.length,
|
|
18846
|
-
...description ? { description } : {},
|
|
18847
|
-
...labels ? { labels } : {}
|
|
18848
|
-
};
|
|
18849
|
-
const meta = await store.put(bytes, attachment, ownerType, ownerId, attachedBy);
|
|
18850
|
-
let backend = "legacy";
|
|
18851
|
-
try {
|
|
18852
|
-
const v2 = createAttachmentStoreV2(getProjectRoot4());
|
|
18853
|
-
const v2Result = await v2.put(ownerId, {
|
|
18854
|
-
name: absPath.split(/[\\/]/).pop() ?? meta.sha256.slice(0, 12),
|
|
18855
|
-
data: new Uint8Array(bytes),
|
|
18856
|
-
contentType: mime
|
|
18857
|
-
});
|
|
18858
|
-
backend = v2Result.backend;
|
|
18859
|
-
} catch {
|
|
18860
|
-
backend = await resolveAttachmentBackend();
|
|
18861
|
-
}
|
|
18862
|
-
import("@cleocode/core/internal").then(
|
|
18863
|
-
({ ensureLlmtxtNode }) => ensureLlmtxtNode(
|
|
18864
|
-
getProjectRoot4(),
|
|
18865
|
-
meta.sha256,
|
|
18866
|
-
`${ownerType}:${ownerId}`,
|
|
18867
|
-
absPath.split("/").pop() ?? meta.sha256.slice(0, 12)
|
|
18868
|
-
)
|
|
18869
|
-
).catch(() => {
|
|
18870
|
-
});
|
|
18871
|
-
return {
|
|
18872
|
-
meta: {
|
|
18873
|
-
...dispatchMeta("mutate", "docs", operation, startTime),
|
|
18874
|
-
attachmentBackend: backend
|
|
18875
|
-
},
|
|
18876
|
-
success: true,
|
|
18877
|
-
data: {
|
|
18878
|
-
attachmentId: meta.id,
|
|
18879
|
-
sha256: meta.sha256,
|
|
18880
|
-
refCount: meta.refCount,
|
|
18881
|
-
kind: "local-file",
|
|
18882
|
-
ownerId,
|
|
18883
|
-
ownerType
|
|
18884
|
-
}
|
|
18885
|
-
};
|
|
18886
|
-
}
|
|
18887
|
-
if (url) {
|
|
18888
|
-
const attachment = {
|
|
18889
|
-
kind: "url",
|
|
18890
|
-
url,
|
|
18891
|
-
...description ? { description } : {},
|
|
18892
|
-
...labels ? { labels } : {}
|
|
18893
|
-
};
|
|
18894
|
-
const urlBytes = Buffer.from(url, "utf-8");
|
|
18895
|
-
const meta = await store.put(urlBytes, attachment, ownerType, ownerId, attachedBy);
|
|
18896
|
-
import("@cleocode/core/internal").then(
|
|
18897
|
-
({ ensureLlmtxtNode }) => ensureLlmtxtNode(getProjectRoot4(), meta.sha256, `${ownerType}:${ownerId}`, url)
|
|
18898
|
-
).catch(() => {
|
|
18899
|
-
});
|
|
18900
|
-
const backend = "legacy";
|
|
18901
|
-
return {
|
|
18902
|
-
meta: {
|
|
18903
|
-
...dispatchMeta("mutate", "docs", operation, startTime),
|
|
18904
|
-
attachmentBackend: backend
|
|
18905
|
-
},
|
|
18906
|
-
success: true,
|
|
18907
|
-
data: {
|
|
18908
|
-
attachmentId: meta.id,
|
|
18909
|
-
sha256: meta.sha256,
|
|
18910
|
-
refCount: meta.refCount,
|
|
18911
|
-
kind: "url",
|
|
18912
|
-
url,
|
|
18913
|
-
ownerId,
|
|
18914
|
-
ownerType
|
|
18915
|
-
}
|
|
18916
|
-
};
|
|
18917
|
-
}
|
|
18918
|
-
return errorResult(
|
|
18919
|
-
"mutate",
|
|
18920
|
-
"docs",
|
|
18921
|
-
operation,
|
|
18922
|
-
"E_INVALID_INPUT",
|
|
18923
|
-
"Unreachable: no file or url",
|
|
18924
|
-
startTime
|
|
18925
|
-
);
|
|
18926
|
-
}
|
|
18927
|
-
// ── docs.remove ──────────────────────────────────────────────────
|
|
18928
|
-
case "remove": {
|
|
18929
|
-
const ref = params?.attachmentRef;
|
|
18930
|
-
const fromOwner = params?.from;
|
|
18931
|
-
if (!ref) {
|
|
18932
|
-
return errorResult(
|
|
18933
|
-
"mutate",
|
|
18934
|
-
"docs",
|
|
18935
|
-
operation,
|
|
18936
|
-
"E_INVALID_INPUT",
|
|
18937
|
-
"attachmentRef is required (attachment ID or SHA-256 hex)",
|
|
18938
|
-
startTime
|
|
18939
|
-
);
|
|
18940
|
-
}
|
|
18941
|
-
if (!fromOwner) {
|
|
18942
|
-
return errorResult(
|
|
18943
|
-
"mutate",
|
|
18944
|
-
"docs",
|
|
18945
|
-
operation,
|
|
18946
|
-
"E_INVALID_INPUT",
|
|
18947
|
-
"--from <ownerId> is required",
|
|
18948
|
-
startTime
|
|
18949
|
-
);
|
|
18950
|
-
}
|
|
18951
|
-
const store = createAttachmentStore();
|
|
18952
|
-
const ownerType = inferOwnerType(fromOwner);
|
|
18953
|
-
let attachmentId = ref;
|
|
18954
|
-
if (/^[0-9a-f]{64}$/i.test(ref)) {
|
|
18955
|
-
const result = await store.get(ref);
|
|
18956
|
-
if (!result) {
|
|
18957
|
-
return errorResult(
|
|
18958
|
-
"mutate",
|
|
18959
|
-
"docs",
|
|
18960
|
-
operation,
|
|
18961
|
-
"E_NOT_FOUND",
|
|
18962
|
-
`No attachment found with SHA-256: ${ref}`,
|
|
18963
|
-
startTime
|
|
18964
|
-
);
|
|
18965
|
-
}
|
|
18966
|
-
attachmentId = result.metadata.id;
|
|
18967
|
-
}
|
|
18968
|
-
const derefResult = await store.deref(attachmentId, ownerType, fromOwner);
|
|
18969
|
-
if (derefResult.status === "not-found") {
|
|
18970
|
-
return errorResult(
|
|
18971
|
-
"mutate",
|
|
18972
|
-
"docs",
|
|
18973
|
-
operation,
|
|
18974
|
-
"E_NOT_FOUND",
|
|
18975
|
-
`Attachment ref not found: ${attachmentId} on owner ${fromOwner}`,
|
|
18976
|
-
startTime
|
|
18977
|
-
);
|
|
18978
|
-
}
|
|
18979
|
-
const blobPurged = derefResult.status === "removed";
|
|
18980
|
-
const refCountAfter = derefResult.status === "derefd" ? derefResult.refCountAfter : 0;
|
|
18981
|
-
try {
|
|
18982
|
-
const v2 = createAttachmentStoreV2(getProjectRoot4());
|
|
18983
|
-
await v2.remove(attachmentId, fromOwner);
|
|
18984
|
-
} catch {
|
|
18985
|
-
}
|
|
18986
|
-
const backend = await resolveAttachmentBackend();
|
|
18987
|
-
return {
|
|
18988
|
-
meta: {
|
|
18989
|
-
...dispatchMeta("mutate", "docs", operation, startTime),
|
|
18990
|
-
attachmentBackend: backend
|
|
18991
|
-
},
|
|
18992
|
-
success: true,
|
|
18993
|
-
data: {
|
|
18994
|
-
removed: blobPurged,
|
|
18995
|
-
attachmentId,
|
|
18996
|
-
from: fromOwner,
|
|
18997
|
-
refCountAfter,
|
|
18998
|
-
blobPurged
|
|
18999
|
-
}
|
|
19000
|
-
};
|
|
19001
|
-
}
|
|
19002
|
-
default:
|
|
19003
|
-
return unsupportedOp("mutate", "docs", operation, startTime);
|
|
19004
|
-
}
|
|
19104
|
+
const envelope = await typedDispatch(
|
|
19105
|
+
_docsTypedHandler,
|
|
19106
|
+
operation,
|
|
19107
|
+
params ?? {}
|
|
19108
|
+
);
|
|
19109
|
+
return docsEnvelopeToResponse(envelope, "mutate", operation, startTime);
|
|
19005
19110
|
} catch (error) {
|
|
19006
19111
|
return handleErrorResult("mutate", "docs", operation, error, startTime);
|
|
19007
19112
|
}
|
|
@@ -19009,6 +19114,7 @@ var init_docs = __esm({
|
|
|
19009
19114
|
// -----------------------------------------------------------------------
|
|
19010
19115
|
// Supported operations
|
|
19011
19116
|
// -----------------------------------------------------------------------
|
|
19117
|
+
/** Declared operations for introspection and validation. */
|
|
19012
19118
|
getSupportedOperations() {
|
|
19013
19119
|
return {
|
|
19014
19120
|
query: ["list", "fetch", "generate"],
|
|
@@ -19273,7 +19379,7 @@ var init_memory2 = __esm({
|
|
|
19273
19379
|
switch (operation) {
|
|
19274
19380
|
case "find": {
|
|
19275
19381
|
const query = paramStringRequired(params, "query");
|
|
19276
|
-
if (!query)
|
|
19382
|
+
if (!query)
|
|
19277
19383
|
return errorResult(
|
|
19278
19384
|
"query",
|
|
19279
19385
|
"memory",
|
|
@@ -19282,24 +19388,27 @@ var init_memory2 = __esm({
|
|
|
19282
19388
|
"query is required",
|
|
19283
19389
|
startTime
|
|
19284
19390
|
);
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
|
|
19294
|
-
|
|
19295
|
-
|
|
19296
|
-
|
|
19391
|
+
return wrapResult(
|
|
19392
|
+
await memoryFind(
|
|
19393
|
+
{
|
|
19394
|
+
query,
|
|
19395
|
+
limit: paramNumber(params, "limit"),
|
|
19396
|
+
tables: paramStringArray(params, "tables"),
|
|
19397
|
+
dateStart: paramString(params, "dateStart"),
|
|
19398
|
+
dateEnd: paramString(params, "dateEnd"),
|
|
19399
|
+
agent: paramString(params, "agent")
|
|
19400
|
+
},
|
|
19401
|
+
projectRoot
|
|
19402
|
+
),
|
|
19403
|
+
"query",
|
|
19404
|
+
"memory",
|
|
19405
|
+
operation,
|
|
19406
|
+
startTime
|
|
19297
19407
|
);
|
|
19298
|
-
return wrapResult(result, "query", "memory", operation, startTime);
|
|
19299
19408
|
}
|
|
19300
19409
|
case "timeline": {
|
|
19301
19410
|
const anchor = paramStringRequired(params, "anchor");
|
|
19302
|
-
if (!anchor)
|
|
19411
|
+
if (!anchor)
|
|
19303
19412
|
return errorResult(
|
|
19304
19413
|
"query",
|
|
19305
19414
|
"memory",
|
|
@@ -19308,20 +19417,24 @@ var init_memory2 = __esm({
|
|
|
19308
19417
|
"anchor is required",
|
|
19309
19418
|
startTime
|
|
19310
19419
|
);
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19420
|
+
return wrapResult(
|
|
19421
|
+
await memoryTimeline(
|
|
19422
|
+
{
|
|
19423
|
+
anchor,
|
|
19424
|
+
depthBefore: paramNumber(params, "depthBefore"),
|
|
19425
|
+
depthAfter: paramNumber(params, "depthAfter")
|
|
19426
|
+
},
|
|
19427
|
+
projectRoot
|
|
19428
|
+
),
|
|
19429
|
+
"query",
|
|
19430
|
+
"memory",
|
|
19431
|
+
operation,
|
|
19432
|
+
startTime
|
|
19319
19433
|
);
|
|
19320
|
-
return wrapResult(result, "query", "memory", operation, startTime);
|
|
19321
19434
|
}
|
|
19322
19435
|
case "fetch": {
|
|
19323
19436
|
const ids = paramStringArray(params, "ids");
|
|
19324
|
-
if (!ids || ids.length === 0)
|
|
19437
|
+
if (!ids || ids.length === 0)
|
|
19325
19438
|
return errorResult(
|
|
19326
19439
|
"query",
|
|
19327
19440
|
"memory",
|
|
@@ -19330,9 +19443,13 @@ var init_memory2 = __esm({
|
|
|
19330
19443
|
"ids is required (non-empty array)",
|
|
19331
19444
|
startTime
|
|
19332
19445
|
);
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19446
|
+
return wrapResult(
|
|
19447
|
+
await memoryFetch({ ids }, projectRoot),
|
|
19448
|
+
"query",
|
|
19449
|
+
"memory",
|
|
19450
|
+
operation,
|
|
19451
|
+
startTime
|
|
19452
|
+
);
|
|
19336
19453
|
}
|
|
19337
19454
|
case "decision.find": {
|
|
19338
19455
|
const result = await memoryDecisionFind(
|
|
@@ -20786,6 +20903,10 @@ var init_memory2 = __esm({
|
|
|
20786
20903
|
return handleErrorResult("mutate", "memory", operation, rollbackErr, startTime);
|
|
20787
20904
|
}
|
|
20788
20905
|
}
|
|
20906
|
+
// T1147 W7 — sweep mutate operations (approve, rollback) delegate to query handler
|
|
20907
|
+
// which already handles all sweep sub-commands via a unified case block.
|
|
20908
|
+
case "sweep":
|
|
20909
|
+
return this.query(operation, params);
|
|
20789
20910
|
default:
|
|
20790
20911
|
return unsupportedOp("mutate", "memory", operation, startTime);
|
|
20791
20912
|
}
|
|
@@ -20862,6 +20983,8 @@ var init_memory2 = __esm({
|
|
|
20862
20983
|
"precompact-flush",
|
|
20863
20984
|
// T1006 — write a diary-typed observation
|
|
20864
20985
|
"diary.write",
|
|
20986
|
+
// T1147 W7 — sweep mutate operations (approve, rollback)
|
|
20987
|
+
"sweep",
|
|
20865
20988
|
// T1003 — staged backfill operations
|
|
20866
20989
|
"backfill.run",
|
|
20867
20990
|
"backfill.approve",
|
|
@@ -21692,6 +21815,45 @@ import {
|
|
|
21692
21815
|
getNexusNativeDb as getNexusNativeDb2,
|
|
21693
21816
|
getProjectRoot as getProjectRoot7
|
|
21694
21817
|
} from "@cleocode/core/internal";
|
|
21818
|
+
function nexusQueryEnvelopeToResponse(envelope, operation, startTime) {
|
|
21819
|
+
const env = envelope;
|
|
21820
|
+
let pageMetadata = env.page;
|
|
21821
|
+
let resultData = env.data;
|
|
21822
|
+
if (!pageMetadata && env.success && resultData && typeof resultData === "object") {
|
|
21823
|
+
const dataObj = resultData;
|
|
21824
|
+
if ("page" in dataObj && dataObj.page) {
|
|
21825
|
+
pageMetadata = dataObj.page;
|
|
21826
|
+
const { page: _removed, ...cleanData } = dataObj;
|
|
21827
|
+
resultData = cleanData;
|
|
21828
|
+
}
|
|
21829
|
+
}
|
|
21830
|
+
return wrapResult(
|
|
21831
|
+
{
|
|
21832
|
+
success: env.success,
|
|
21833
|
+
data: resultData,
|
|
21834
|
+
page: pageMetadata,
|
|
21835
|
+
error: env.error ? { code: String(env.error.code), message: env.error.message } : void 0
|
|
21836
|
+
},
|
|
21837
|
+
"query",
|
|
21838
|
+
"nexus",
|
|
21839
|
+
operation,
|
|
21840
|
+
startTime
|
|
21841
|
+
);
|
|
21842
|
+
}
|
|
21843
|
+
function nexusMutateEnvelopeToResponse(envelope, operation, startTime) {
|
|
21844
|
+
const env = envelope;
|
|
21845
|
+
return wrapResult(
|
|
21846
|
+
{
|
|
21847
|
+
success: env.success,
|
|
21848
|
+
data: env.data,
|
|
21849
|
+
error: env.error ? { code: String(env.error.code), message: env.error.message } : void 0
|
|
21850
|
+
},
|
|
21851
|
+
"mutate",
|
|
21852
|
+
"nexus",
|
|
21853
|
+
operation,
|
|
21854
|
+
startTime
|
|
21855
|
+
);
|
|
21856
|
+
}
|
|
21695
21857
|
async function handleTopEntries(operation, params, startTime) {
|
|
21696
21858
|
const rawLimit = params?.limit;
|
|
21697
21859
|
const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) && rawLimit > 0 ? Math.floor(rawLimit) : 20;
|
|
@@ -22038,7 +22200,7 @@ async function handleImpact(operation, params, startTime) {
|
|
|
22038
22200
|
return handleErrorResult("query", "nexus", operation, dbErr, startTime);
|
|
22039
22201
|
}
|
|
22040
22202
|
}
|
|
22041
|
-
var _nexusTypedHandler,
|
|
22203
|
+
var _nexusTypedHandler, QUERY_OPS4, MUTATE_OPS4, NexusHandler, IMPACT_REVERSE_TYPES;
|
|
22042
22204
|
var init_nexus2 = __esm({
|
|
22043
22205
|
"packages/cleo/src/dispatch/domains/nexus.ts"() {
|
|
22044
22206
|
"use strict";
|
|
@@ -22354,7 +22516,7 @@ var init_nexus2 = __esm({
|
|
|
22354
22516
|
},
|
|
22355
22517
|
"sigil.sync": async (_params) => wrapCoreResult(await nexusSigilSync(), "sigil.sync")
|
|
22356
22518
|
});
|
|
22357
|
-
|
|
22519
|
+
QUERY_OPS4 = /* @__PURE__ */ new Set([
|
|
22358
22520
|
"share.status",
|
|
22359
22521
|
"status",
|
|
22360
22522
|
"list",
|
|
@@ -22386,7 +22548,7 @@ var init_nexus2 = __esm({
|
|
|
22386
22548
|
"profile.get",
|
|
22387
22549
|
"sigil.list"
|
|
22388
22550
|
]);
|
|
22389
|
-
|
|
22551
|
+
MUTATE_OPS4 = /* @__PURE__ */ new Set([
|
|
22390
22552
|
"share.snapshot.export",
|
|
22391
22553
|
"share.snapshot.import",
|
|
22392
22554
|
"init",
|
|
@@ -22415,7 +22577,7 @@ var init_nexus2 = __esm({
|
|
|
22415
22577
|
*/
|
|
22416
22578
|
async query(operation, params) {
|
|
22417
22579
|
const startTime = Date.now();
|
|
22418
|
-
if (!
|
|
22580
|
+
if (!QUERY_OPS4.has(operation)) {
|
|
22419
22581
|
return unsupportedOp("query", "nexus", operation, startTime);
|
|
22420
22582
|
}
|
|
22421
22583
|
if (operation === "top-entries") {
|
|
@@ -22430,29 +22592,7 @@ var init_nexus2 = __esm({
|
|
|
22430
22592
|
operation,
|
|
22431
22593
|
params ?? {}
|
|
22432
22594
|
);
|
|
22433
|
-
|
|
22434
|
-
let pageMetadata = env.page;
|
|
22435
|
-
let resultData = env.data;
|
|
22436
|
-
if (!pageMetadata && env.success && resultData && typeof resultData === "object") {
|
|
22437
|
-
const dataObj = resultData;
|
|
22438
|
-
if ("page" in dataObj && dataObj.page) {
|
|
22439
|
-
pageMetadata = dataObj.page;
|
|
22440
|
-
const { page: _removed, ...cleanData } = dataObj;
|
|
22441
|
-
resultData = cleanData;
|
|
22442
|
-
}
|
|
22443
|
-
}
|
|
22444
|
-
return wrapResult(
|
|
22445
|
-
{
|
|
22446
|
-
success: env.success,
|
|
22447
|
-
data: resultData,
|
|
22448
|
-
page: pageMetadata,
|
|
22449
|
-
error: env.error ? { code: String(env.error.code), message: env.error.message } : void 0
|
|
22450
|
-
},
|
|
22451
|
-
"query",
|
|
22452
|
-
"nexus",
|
|
22453
|
-
operation,
|
|
22454
|
-
startTime
|
|
22455
|
-
);
|
|
22595
|
+
return nexusQueryEnvelopeToResponse(envelope, operation, startTime);
|
|
22456
22596
|
} catch (error) {
|
|
22457
22597
|
getLogger9("domain:nexus").error(
|
|
22458
22598
|
{ gateway: "query", domain: "nexus", operation, err: error },
|
|
@@ -22469,7 +22609,7 @@ var init_nexus2 = __esm({
|
|
|
22469
22609
|
*/
|
|
22470
22610
|
async mutate(operation, params) {
|
|
22471
22611
|
const startTime = Date.now();
|
|
22472
|
-
if (!
|
|
22612
|
+
if (!MUTATE_OPS4.has(operation)) {
|
|
22473
22613
|
return unsupportedOp("mutate", "nexus", operation, startTime);
|
|
22474
22614
|
}
|
|
22475
22615
|
try {
|
|
@@ -22478,18 +22618,7 @@ var init_nexus2 = __esm({
|
|
|
22478
22618
|
operation,
|
|
22479
22619
|
params ?? {}
|
|
22480
22620
|
);
|
|
22481
|
-
|
|
22482
|
-
return wrapResult(
|
|
22483
|
-
{
|
|
22484
|
-
success: env.success,
|
|
22485
|
-
data: env.data,
|
|
22486
|
-
error: env.error ? { code: String(env.error.code), message: env.error.message } : void 0
|
|
22487
|
-
},
|
|
22488
|
-
"mutate",
|
|
22489
|
-
"nexus",
|
|
22490
|
-
operation,
|
|
22491
|
-
startTime
|
|
22492
|
-
);
|
|
22621
|
+
return nexusMutateEnvelopeToResponse(envelope, operation, startTime);
|
|
22493
22622
|
} catch (error) {
|
|
22494
22623
|
getLogger9("domain:nexus").error(
|
|
22495
22624
|
{ gateway: "mutate", domain: "nexus", operation, err: error },
|
|
@@ -22501,8 +22630,8 @@ var init_nexus2 = __esm({
|
|
|
22501
22630
|
/** Declared operations for introspection and validation. */
|
|
22502
22631
|
getSupportedOperations() {
|
|
22503
22632
|
return {
|
|
22504
|
-
query: Array.from(
|
|
22505
|
-
mutate: Array.from(
|
|
22633
|
+
query: Array.from(QUERY_OPS4),
|
|
22634
|
+
mutate: Array.from(MUTATE_OPS4)
|
|
22506
22635
|
};
|
|
22507
22636
|
}
|
|
22508
22637
|
};
|
|
@@ -27407,7 +27536,7 @@ async function lookupApprovalByTokenForDispatch(token) {
|
|
|
27407
27536
|
const db = await acquireDb();
|
|
27408
27537
|
return getPlaybookApprovalByToken(db, token);
|
|
27409
27538
|
}
|
|
27410
|
-
var __playbookRuntimeOverrides, _playbookTypedHandler,
|
|
27539
|
+
var __playbookRuntimeOverrides, _playbookTypedHandler, QUERY_OPS5, MUTATE_OPS5, PlaybookHandler;
|
|
27411
27540
|
var init_playbook2 = __esm({
|
|
27412
27541
|
"packages/cleo/src/dispatch/domains/playbook.ts"() {
|
|
27413
27542
|
"use strict";
|
|
@@ -27673,15 +27802,15 @@ var init_playbook2 = __esm({
|
|
|
27673
27802
|
}
|
|
27674
27803
|
}
|
|
27675
27804
|
});
|
|
27676
|
-
|
|
27677
|
-
|
|
27805
|
+
QUERY_OPS5 = /* @__PURE__ */ new Set(["status", "list", "validate"]);
|
|
27806
|
+
MUTATE_OPS5 = /* @__PURE__ */ new Set(["run", "resume"]);
|
|
27678
27807
|
PlaybookHandler = class {
|
|
27679
27808
|
/**
|
|
27680
27809
|
* Query gateway — `status`, `list`, and `validate`.
|
|
27681
27810
|
*/
|
|
27682
27811
|
async query(operation, params) {
|
|
27683
27812
|
const startTime = Date.now();
|
|
27684
|
-
if (!
|
|
27813
|
+
if (!QUERY_OPS5.has(operation)) {
|
|
27685
27814
|
return unsupportedOp("query", "playbook", operation, startTime);
|
|
27686
27815
|
}
|
|
27687
27816
|
try {
|
|
@@ -27709,7 +27838,7 @@ var init_playbook2 = __esm({
|
|
|
27709
27838
|
*/
|
|
27710
27839
|
async mutate(operation, params) {
|
|
27711
27840
|
const startTime = Date.now();
|
|
27712
|
-
if (!
|
|
27841
|
+
if (!MUTATE_OPS5.has(operation)) {
|
|
27713
27842
|
return unsupportedOp("mutate", "playbook", operation, startTime);
|
|
27714
27843
|
}
|
|
27715
27844
|
try {
|
|
@@ -28220,6 +28349,31 @@ async function handleWorktreeCleanup(projectRoot, taskIds, startTime) {
|
|
|
28220
28349
|
return handleErrorResult("mutate", "orchestrate", "worktree.cleanup", error, startTime);
|
|
28221
28350
|
}
|
|
28222
28351
|
}
|
|
28352
|
+
async function handleWorktreePrune(projectRoot, taskId, startTime) {
|
|
28353
|
+
try {
|
|
28354
|
+
const { pruneWorktree, pruneOrphanedWorktrees } = await import("@cleocode/core/internal");
|
|
28355
|
+
if (taskId) {
|
|
28356
|
+
const result2 = pruneWorktree(taskId, projectRoot);
|
|
28357
|
+
return {
|
|
28358
|
+
meta: dispatchMeta("mutate", "orchestrate", "worktree.prune", startTime),
|
|
28359
|
+
success: true,
|
|
28360
|
+
data: result2
|
|
28361
|
+
};
|
|
28362
|
+
}
|
|
28363
|
+
const result = pruneOrphanedWorktrees(projectRoot, void 0);
|
|
28364
|
+
return {
|
|
28365
|
+
meta: dispatchMeta("mutate", "orchestrate", "worktree.prune", startTime),
|
|
28366
|
+
success: true,
|
|
28367
|
+
data: { ...result, mode: "bulk" }
|
|
28368
|
+
};
|
|
28369
|
+
} catch (error) {
|
|
28370
|
+
getLogger11("domain:orchestrate").error(
|
|
28371
|
+
{ operation: "worktree.prune", taskId, err: error },
|
|
28372
|
+
error instanceof Error ? error.message : String(error)
|
|
28373
|
+
);
|
|
28374
|
+
return handleErrorResult("mutate", "orchestrate", "worktree.prune", error, startTime);
|
|
28375
|
+
}
|
|
28376
|
+
}
|
|
28223
28377
|
var ivtrHandler, OrchestrateHandler, FANOUT_MANIFEST_MAX_SIZE, fanoutManifestStore;
|
|
28224
28378
|
var init_orchestrate2 = __esm({
|
|
28225
28379
|
"packages/cleo/src/dispatch/domains/orchestrate.ts"() {
|
|
@@ -28287,9 +28441,10 @@ var init_orchestrate2 = __esm({
|
|
|
28287
28441
|
const result = await orchestrateAnalyze(epicId, projectRoot, mode);
|
|
28288
28442
|
return wrapResult(result, "query", "orchestrate", "analyze", startTime);
|
|
28289
28443
|
}
|
|
28444
|
+
// T408: prompt-based CANT team routing (ADR-030 §5: query, idempotent, advisory)
|
|
28290
28445
|
case "classify": {
|
|
28291
28446
|
const request = params?.request;
|
|
28292
|
-
if (!request)
|
|
28447
|
+
if (!request)
|
|
28293
28448
|
return errorResult(
|
|
28294
28449
|
"query",
|
|
28295
28450
|
"orchestrate",
|
|
@@ -28298,10 +28453,13 @@ var init_orchestrate2 = __esm({
|
|
|
28298
28453
|
"request is required",
|
|
28299
28454
|
startTime
|
|
28300
28455
|
);
|
|
28301
|
-
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28456
|
+
return wrapResult(
|
|
28457
|
+
await orchestrateClassify(request, params?.context, projectRoot),
|
|
28458
|
+
"query",
|
|
28459
|
+
"orchestrate",
|
|
28460
|
+
operation,
|
|
28461
|
+
startTime
|
|
28462
|
+
);
|
|
28305
28463
|
}
|
|
28306
28464
|
case "fanout.status": {
|
|
28307
28465
|
const manifestEntryId = params?.manifestEntryId;
|
|
@@ -28594,6 +28752,11 @@ var init_orchestrate2 = __esm({
|
|
|
28594
28752
|
const taskIds = params?.taskIds;
|
|
28595
28753
|
return handleWorktreeCleanup(projectRoot, taskIds, startTime);
|
|
28596
28754
|
}
|
|
28755
|
+
// T1462 — Single-task worktree prune (used by `cleo orchestrate prune`)
|
|
28756
|
+
case "worktree.prune": {
|
|
28757
|
+
const taskId = params?.taskId;
|
|
28758
|
+
return handleWorktreePrune(projectRoot, taskId, startTime);
|
|
28759
|
+
}
|
|
28597
28760
|
case "parallel": {
|
|
28598
28761
|
return routeByParam(params, "action", {
|
|
28599
28762
|
start: async () => {
|
|
@@ -28650,9 +28813,10 @@ var init_orchestrate2 = __esm({
|
|
|
28650
28813
|
}
|
|
28651
28814
|
});
|
|
28652
28815
|
}
|
|
28816
|
+
// T409: Promise.allSettled fanout wrapper (ADR-030 §5: not idempotent, concurrent)
|
|
28653
28817
|
case "fanout": {
|
|
28654
28818
|
const items = params?.items;
|
|
28655
|
-
if (!items || !Array.isArray(items) || items.length === 0)
|
|
28819
|
+
if (!items || !Array.isArray(items) || items.length === 0)
|
|
28656
28820
|
return errorResult(
|
|
28657
28821
|
"mutate",
|
|
28658
28822
|
"orchestrate",
|
|
@@ -28661,9 +28825,13 @@ var init_orchestrate2 = __esm({
|
|
|
28661
28825
|
"items array is required and must be non-empty",
|
|
28662
28826
|
startTime
|
|
28663
28827
|
);
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28828
|
+
return wrapResult(
|
|
28829
|
+
await orchestrateFanout(items, projectRoot),
|
|
28830
|
+
"mutate",
|
|
28831
|
+
"orchestrate",
|
|
28832
|
+
operation,
|
|
28833
|
+
startTime
|
|
28834
|
+
);
|
|
28667
28835
|
}
|
|
28668
28836
|
case "tessera.instantiate": {
|
|
28669
28837
|
const templateId = params?.templateId;
|
|
@@ -28785,7 +28953,9 @@ var init_orchestrate2 = __esm({
|
|
|
28785
28953
|
"reject",
|
|
28786
28954
|
// T1118 L1 — Worktree lifecycle
|
|
28787
28955
|
"worktree.complete",
|
|
28788
|
-
"worktree.cleanup"
|
|
28956
|
+
"worktree.cleanup",
|
|
28957
|
+
// T1462 — Single-task worktree prune
|
|
28958
|
+
"worktree.prune"
|
|
28789
28959
|
]
|
|
28790
28960
|
};
|
|
28791
28961
|
}
|
|
@@ -29003,6 +29173,44 @@ async function chainAdvanceOp(params) {
|
|
|
29003
29173
|
getProjectRoot10()
|
|
29004
29174
|
);
|
|
29005
29175
|
}
|
|
29176
|
+
function pipelinePhaseListResponse(envelope, params, operation, startTime) {
|
|
29177
|
+
const listData = envelope.data ?? {};
|
|
29178
|
+
const phases = listData?.phases ?? [];
|
|
29179
|
+
const total = listData?.summary?.total ?? phases.length;
|
|
29180
|
+
const { limit, offset } = getListParams(params);
|
|
29181
|
+
const page = paginate5(phases, limit, offset);
|
|
29182
|
+
return {
|
|
29183
|
+
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29184
|
+
success: true,
|
|
29185
|
+
data: { ...listData, phases: page.items, total, filtered: total },
|
|
29186
|
+
page: page.page
|
|
29187
|
+
};
|
|
29188
|
+
}
|
|
29189
|
+
function pipelineChainListResponse(envelope, params, operation, startTime) {
|
|
29190
|
+
const rawData = envelope.data ?? { _chains: [] };
|
|
29191
|
+
const chains = rawData._chains ?? [];
|
|
29192
|
+
const { limit, offset } = getListParams(params);
|
|
29193
|
+
const page = paginate5(chains, limit, offset);
|
|
29194
|
+
return {
|
|
29195
|
+
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29196
|
+
success: true,
|
|
29197
|
+
data: { chains: page.items, total: chains.length, filtered: chains.length },
|
|
29198
|
+
page: page.page
|
|
29199
|
+
};
|
|
29200
|
+
}
|
|
29201
|
+
function pipelineEnvelopeResponse(envelope, operation, startTime) {
|
|
29202
|
+
const envelopeData = envelope.data;
|
|
29203
|
+
const enginePage = envelopeData?._enginePage;
|
|
29204
|
+
const responseData = envelopeData?._enginePage !== void 0 ? (({ _enginePage: _p, ...rest }) => rest)(
|
|
29205
|
+
envelopeData
|
|
29206
|
+
) : envelopeData;
|
|
29207
|
+
return {
|
|
29208
|
+
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29209
|
+
success: true,
|
|
29210
|
+
data: responseData,
|
|
29211
|
+
...enginePage ? { page: enginePage } : {}
|
|
29212
|
+
};
|
|
29213
|
+
}
|
|
29006
29214
|
var coreOps, _pipelineTypedHandler, PipelineHandler;
|
|
29007
29215
|
var init_pipeline3 = __esm({
|
|
29008
29216
|
"packages/cleo/src/dispatch/domains/pipeline.ts"() {
|
|
@@ -29369,52 +29577,11 @@ var init_pipeline3 = __esm({
|
|
|
29369
29577
|
}
|
|
29370
29578
|
};
|
|
29371
29579
|
}
|
|
29372
|
-
if (operation === "phase.list")
|
|
29373
|
-
|
|
29374
|
-
|
|
29375
|
-
|
|
29376
|
-
|
|
29377
|
-
const { limit, offset } = getListParams(params);
|
|
29378
|
-
const page = paginate5(phases, limit, offset);
|
|
29379
|
-
return {
|
|
29380
|
-
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29381
|
-
success: true,
|
|
29382
|
-
data: {
|
|
29383
|
-
...listData,
|
|
29384
|
-
phases: page.items,
|
|
29385
|
-
total,
|
|
29386
|
-
filtered: total
|
|
29387
|
-
},
|
|
29388
|
-
page: page.page
|
|
29389
|
-
};
|
|
29390
|
-
}
|
|
29391
|
-
if (operation === "chain.list") {
|
|
29392
|
-
const rawData = envelope.data;
|
|
29393
|
-
const chains = rawData._chains ?? [];
|
|
29394
|
-
const { limit, offset } = getListParams(params);
|
|
29395
|
-
const page = paginate5(chains, limit, offset);
|
|
29396
|
-
return {
|
|
29397
|
-
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29398
|
-
success: true,
|
|
29399
|
-
data: {
|
|
29400
|
-
chains: page.items,
|
|
29401
|
-
total: chains.length,
|
|
29402
|
-
filtered: chains.length
|
|
29403
|
-
},
|
|
29404
|
-
page: page.page
|
|
29405
|
-
};
|
|
29406
|
-
}
|
|
29407
|
-
const envelopeData = envelope.data;
|
|
29408
|
-
const enginePage = envelopeData?._enginePage;
|
|
29409
|
-
const responseData = envelopeData?._enginePage !== void 0 ? (({ _enginePage: _p, ...rest }) => rest)(
|
|
29410
|
-
envelopeData
|
|
29411
|
-
) : envelopeData;
|
|
29412
|
-
return {
|
|
29413
|
-
meta: dispatchMeta("query", "pipeline", operation, startTime),
|
|
29414
|
-
success: true,
|
|
29415
|
-
data: responseData,
|
|
29416
|
-
...enginePage ? { page: enginePage } : {}
|
|
29417
|
-
};
|
|
29580
|
+
if (operation === "phase.list")
|
|
29581
|
+
return pipelinePhaseListResponse(envelope, params, operation, startTime);
|
|
29582
|
+
if (operation === "chain.list")
|
|
29583
|
+
return pipelineChainListResponse(envelope, params, operation, startTime);
|
|
29584
|
+
return pipelineEnvelopeResponse(envelope, operation, startTime);
|
|
29418
29585
|
} catch (error) {
|
|
29419
29586
|
getLogger12("domain:pipeline").error(
|
|
29420
29587
|
{ gateway: "query", domain: "pipeline", operation, err: error },
|
|
@@ -29549,12 +29716,10 @@ var init_release2 = __esm({
|
|
|
29549
29716
|
const startTime = Date.now();
|
|
29550
29717
|
try {
|
|
29551
29718
|
switch (operation) {
|
|
29552
|
-
// ------------------------------------------------------------------
|
|
29553
29719
|
// release.gate — IVTR gate check (RELEASE-03)
|
|
29554
|
-
// ------------------------------------------------------------------
|
|
29555
29720
|
case "gate": {
|
|
29556
29721
|
const epicId = params?.["epicId"];
|
|
29557
|
-
if (!epicId)
|
|
29722
|
+
if (!epicId)
|
|
29558
29723
|
return errorResult(
|
|
29559
29724
|
"query",
|
|
29560
29725
|
"release",
|
|
@@ -29563,18 +29728,18 @@ var init_release2 = __esm({
|
|
|
29563
29728
|
"epicId is required",
|
|
29564
29729
|
startTime
|
|
29565
29730
|
);
|
|
29566
|
-
|
|
29567
|
-
|
|
29568
|
-
|
|
29569
|
-
|
|
29570
|
-
|
|
29731
|
+
return wrapResult(
|
|
29732
|
+
await releaseGateCheck(epicId, params?.["force"] === true, getProjectRoot11()),
|
|
29733
|
+
"query",
|
|
29734
|
+
"release",
|
|
29735
|
+
operation,
|
|
29736
|
+
startTime
|
|
29737
|
+
);
|
|
29571
29738
|
}
|
|
29572
|
-
// ------------------------------------------------------------------
|
|
29573
29739
|
// release.ivtr-suggest — IVTR auto-suggest (RELEASE-07)
|
|
29574
|
-
// ------------------------------------------------------------------
|
|
29575
29740
|
case "ivtr-suggest": {
|
|
29576
29741
|
const taskId = params?.["taskId"];
|
|
29577
|
-
if (!taskId)
|
|
29742
|
+
if (!taskId)
|
|
29578
29743
|
return errorResult(
|
|
29579
29744
|
"query",
|
|
29580
29745
|
"release",
|
|
@@ -29583,10 +29748,13 @@ var init_release2 = __esm({
|
|
|
29583
29748
|
"taskId is required",
|
|
29584
29749
|
startTime
|
|
29585
29750
|
);
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
|
|
29589
|
-
|
|
29751
|
+
return wrapResult(
|
|
29752
|
+
await releaseIvtrAutoSuggest(taskId, getProjectRoot11()),
|
|
29753
|
+
"query",
|
|
29754
|
+
"release",
|
|
29755
|
+
operation,
|
|
29756
|
+
startTime
|
|
29757
|
+
);
|
|
29590
29758
|
}
|
|
29591
29759
|
default:
|
|
29592
29760
|
return errorResult(
|
|
@@ -29622,13 +29790,10 @@ var init_release2 = __esm({
|
|
|
29622
29790
|
const startTime = Date.now();
|
|
29623
29791
|
try {
|
|
29624
29792
|
switch (operation) {
|
|
29625
|
-
//
|
|
29626
|
-
// release.gate — IVTR gate check (RELEASE-03)
|
|
29627
|
-
// Pre-ship guard: blocks release.ship when tasks are not IVTR released.
|
|
29628
|
-
// ------------------------------------------------------------------
|
|
29793
|
+
// release.gate — IVTR gate check (RELEASE-03, no DB writes)
|
|
29629
29794
|
case "gate": {
|
|
29630
29795
|
const epicId = params?.["epicId"];
|
|
29631
|
-
if (!epicId)
|
|
29796
|
+
if (!epicId)
|
|
29632
29797
|
return errorResult(
|
|
29633
29798
|
"mutate",
|
|
29634
29799
|
"release",
|
|
@@ -29637,19 +29802,18 @@ var init_release2 = __esm({
|
|
|
29637
29802
|
"epicId is required",
|
|
29638
29803
|
startTime
|
|
29639
29804
|
);
|
|
29640
|
-
|
|
29641
|
-
|
|
29642
|
-
|
|
29643
|
-
|
|
29644
|
-
|
|
29805
|
+
return wrapResult(
|
|
29806
|
+
await releaseGateCheck(epicId, params?.["force"] === true, getProjectRoot11()),
|
|
29807
|
+
"mutate",
|
|
29808
|
+
"release",
|
|
29809
|
+
operation,
|
|
29810
|
+
startTime
|
|
29811
|
+
);
|
|
29645
29812
|
}
|
|
29646
|
-
//
|
|
29647
|
-
// release.ivtr-suggest — IVTR auto-suggest (RELEASE-07)
|
|
29648
|
-
// Triggered after ivtr.release succeeds; checks if all siblings are done.
|
|
29649
|
-
// ------------------------------------------------------------------
|
|
29813
|
+
// release.ivtr-suggest — IVTR auto-suggest (RELEASE-07, no DB writes)
|
|
29650
29814
|
case "ivtr-suggest": {
|
|
29651
29815
|
const taskId = params?.["taskId"];
|
|
29652
|
-
if (!taskId)
|
|
29816
|
+
if (!taskId)
|
|
29653
29817
|
return errorResult(
|
|
29654
29818
|
"mutate",
|
|
29655
29819
|
"release",
|
|
@@ -29658,10 +29822,13 @@ var init_release2 = __esm({
|
|
|
29658
29822
|
"taskId is required",
|
|
29659
29823
|
startTime
|
|
29660
29824
|
);
|
|
29661
|
-
|
|
29662
|
-
|
|
29663
|
-
|
|
29664
|
-
|
|
29825
|
+
return wrapResult(
|
|
29826
|
+
await releaseIvtrAutoSuggest(taskId, getProjectRoot11()),
|
|
29827
|
+
"mutate",
|
|
29828
|
+
"release",
|
|
29829
|
+
operation,
|
|
29830
|
+
startTime
|
|
29831
|
+
);
|
|
29665
29832
|
}
|
|
29666
29833
|
default:
|
|
29667
29834
|
return errorResult(
|
|
@@ -29718,7 +29885,7 @@ function envelopeToEngineResult3(envelope) {
|
|
|
29718
29885
|
}
|
|
29719
29886
|
};
|
|
29720
29887
|
}
|
|
29721
|
-
var coreOps2, _sentientTypedHandler,
|
|
29888
|
+
var coreOps2, _sentientTypedHandler, QUERY_OPS6, MUTATE_OPS6, SentientHandler;
|
|
29722
29889
|
var init_sentient2 = __esm({
|
|
29723
29890
|
"packages/cleo/src/dispatch/domains/sentient.ts"() {
|
|
29724
29891
|
"use strict";
|
|
@@ -29838,8 +30005,8 @@ var init_sentient2 = __esm({
|
|
|
29838
30005
|
}
|
|
29839
30006
|
}
|
|
29840
30007
|
});
|
|
29841
|
-
|
|
29842
|
-
|
|
30008
|
+
QUERY_OPS6 = /* @__PURE__ */ new Set(["propose.list", "propose.diff", "allowlist.list"]);
|
|
30009
|
+
MUTATE_OPS6 = /* @__PURE__ */ new Set([
|
|
29843
30010
|
"propose.accept",
|
|
29844
30011
|
"propose.reject",
|
|
29845
30012
|
"propose.run",
|
|
@@ -29872,7 +30039,7 @@ var init_sentient2 = __esm({
|
|
|
29872
30039
|
*/
|
|
29873
30040
|
async query(operation, params) {
|
|
29874
30041
|
const startTime = Date.now();
|
|
29875
|
-
if (!
|
|
30042
|
+
if (!QUERY_OPS6.has(operation)) {
|
|
29876
30043
|
return unsupportedOp("query", "sentient", operation, startTime);
|
|
29877
30044
|
}
|
|
29878
30045
|
try {
|
|
@@ -29900,7 +30067,7 @@ var init_sentient2 = __esm({
|
|
|
29900
30067
|
*/
|
|
29901
30068
|
async mutate(operation, params) {
|
|
29902
30069
|
const startTime = Date.now();
|
|
29903
|
-
if (!
|
|
30070
|
+
if (!MUTATE_OPS6.has(operation)) {
|
|
29904
30071
|
return unsupportedOp("mutate", "sentient", operation, startTime);
|
|
29905
30072
|
}
|
|
29906
30073
|
try {
|
|
@@ -30040,7 +30207,7 @@ async function storeSessionOwnerAuthToken(projectRoot, sessionId, token) {
|
|
|
30040
30207
|
const db = await getDb(projectRoot);
|
|
30041
30208
|
db.update(sessions).set({ ownerAuthToken: token }).where(eq(sessions.id, sessionId)).run();
|
|
30042
30209
|
}
|
|
30043
|
-
var coreOps3, _sessionTypedHandler,
|
|
30210
|
+
var coreOps3, _sessionTypedHandler, QUERY_OPS7, MUTATE_OPS7, SessionHandler;
|
|
30044
30211
|
var init_session3 = __esm({
|
|
30045
30212
|
"packages/cleo/src/dispatch/domains/session.ts"() {
|
|
30046
30213
|
"use strict";
|
|
@@ -30070,10 +30237,12 @@ var init_session3 = __esm({
|
|
|
30070
30237
|
// Query ops
|
|
30071
30238
|
// -------------------------------------------------------------------------
|
|
30072
30239
|
// Engine guarantees data on success; fallback mirrors empty-state shape.
|
|
30240
|
+
// overrideCount included per T1501 / P0-5.
|
|
30073
30241
|
status: async (_params) => wrapCoreResult(await coreOps3.status(), "status", {
|
|
30074
30242
|
hasActiveSession: false,
|
|
30075
30243
|
session: null,
|
|
30076
|
-
taskWork: null
|
|
30244
|
+
taskWork: null,
|
|
30245
|
+
overrideCount: 0
|
|
30077
30246
|
}),
|
|
30078
30247
|
list: async (params) => wrapCoreResult(await coreOps3.list(params), "list"),
|
|
30079
30248
|
// session.show absorbs debrief.show via include param (T5615)
|
|
@@ -30254,7 +30423,7 @@ var init_session3 = __esm({
|
|
|
30254
30423
|
return wrapCoreResult(result, "record.assumption");
|
|
30255
30424
|
}
|
|
30256
30425
|
});
|
|
30257
|
-
|
|
30426
|
+
QUERY_OPS7 = /* @__PURE__ */ new Set([
|
|
30258
30427
|
"status",
|
|
30259
30428
|
"list",
|
|
30260
30429
|
"show",
|
|
@@ -30264,7 +30433,7 @@ var init_session3 = __esm({
|
|
|
30264
30433
|
"handoff.show",
|
|
30265
30434
|
"briefing.show"
|
|
30266
30435
|
]);
|
|
30267
|
-
|
|
30436
|
+
MUTATE_OPS7 = /* @__PURE__ */ new Set([
|
|
30268
30437
|
"start",
|
|
30269
30438
|
"end",
|
|
30270
30439
|
"resume",
|
|
@@ -30285,7 +30454,7 @@ var init_session3 = __esm({
|
|
|
30285
30454
|
*/
|
|
30286
30455
|
async query(operation, params) {
|
|
30287
30456
|
const startTime = Date.now();
|
|
30288
|
-
if (!
|
|
30457
|
+
if (!QUERY_OPS7.has(operation)) {
|
|
30289
30458
|
return unsupportedOp("query", "session", operation, startTime);
|
|
30290
30459
|
}
|
|
30291
30460
|
try {
|
|
@@ -30314,7 +30483,7 @@ var init_session3 = __esm({
|
|
|
30314
30483
|
*/
|
|
30315
30484
|
async mutate(operation, params) {
|
|
30316
30485
|
const startTime = Date.now();
|
|
30317
|
-
if (!
|
|
30486
|
+
if (!MUTATE_OPS7.has(operation)) {
|
|
30318
30487
|
return unsupportedOp("mutate", "session", operation, startTime);
|
|
30319
30488
|
}
|
|
30320
30489
|
try {
|
|
@@ -30362,6 +30531,7 @@ var init_session3 = __esm({
|
|
|
30362
30531
|
});
|
|
30363
30532
|
|
|
30364
30533
|
// packages/cleo/src/dispatch/engines/sticky-engine.ts
|
|
30534
|
+
import { paginate as paginate6 } from "@cleocode/core";
|
|
30365
30535
|
import {
|
|
30366
30536
|
addSticky,
|
|
30367
30537
|
archiveSticky,
|
|
@@ -30381,10 +30551,17 @@ async function stickyAdd(projectRoot, params) {
|
|
|
30381
30551
|
return engineError("E_INTERNAL", String(error));
|
|
30382
30552
|
}
|
|
30383
30553
|
}
|
|
30384
|
-
async function
|
|
30554
|
+
async function stickyListFiltered(projectRoot, filters, limit, offset) {
|
|
30385
30555
|
try {
|
|
30386
|
-
const
|
|
30387
|
-
|
|
30556
|
+
const filteredStickies = await listStickies(filters, projectRoot);
|
|
30557
|
+
const hasFilter = filters.status !== void 0 || filters.color !== void 0 || filters.priority !== void 0 || filters.tags !== void 0 && filters.tags.length > 0;
|
|
30558
|
+
const total = hasFilter ? (await listStickies({}, projectRoot)).length : filteredStickies.length;
|
|
30559
|
+
const page = paginate6(filteredStickies, limit, offset);
|
|
30560
|
+
return {
|
|
30561
|
+
success: true,
|
|
30562
|
+
data: { stickies: page.items, total, filtered: filteredStickies.length },
|
|
30563
|
+
page: page.page
|
|
30564
|
+
};
|
|
30388
30565
|
} catch (error) {
|
|
30389
30566
|
return engineError("E_INTERNAL", String(error));
|
|
30390
30567
|
}
|
|
@@ -30474,14 +30651,13 @@ var init_sticky_engine = __esm({
|
|
|
30474
30651
|
});
|
|
30475
30652
|
|
|
30476
30653
|
// packages/cleo/src/dispatch/domains/sticky.ts
|
|
30477
|
-
import { getLogger as getLogger15, getProjectRoot as getProjectRoot14
|
|
30654
|
+
import { getLogger as getLogger15, getProjectRoot as getProjectRoot14 } from "@cleocode/core";
|
|
30478
30655
|
var StickyHandler;
|
|
30479
30656
|
var init_sticky = __esm({
|
|
30480
30657
|
"packages/cleo/src/dispatch/domains/sticky.ts"() {
|
|
30481
30658
|
"use strict";
|
|
30482
30659
|
init_sticky_engine();
|
|
30483
30660
|
init_base();
|
|
30484
|
-
init_meta2();
|
|
30485
30661
|
StickyHandler = class {
|
|
30486
30662
|
// -----------------------------------------------------------------------
|
|
30487
30663
|
// Query
|
|
@@ -30492,36 +30668,18 @@ var init_sticky = __esm({
|
|
|
30492
30668
|
try {
|
|
30493
30669
|
switch (operation) {
|
|
30494
30670
|
case "list": {
|
|
30495
|
-
const
|
|
30496
|
-
|
|
30497
|
-
|
|
30498
|
-
|
|
30499
|
-
|
|
30500
|
-
|
|
30501
|
-
|
|
30502
|
-
const result = await stickyList(projectRoot, filters);
|
|
30503
|
-
if (!result.success) {
|
|
30504
|
-
return wrapResult(result, "query", "sticky", operation, startTime);
|
|
30505
|
-
}
|
|
30506
|
-
const filteredStickies = result.data?.stickies ?? [];
|
|
30507
|
-
const hasFilter = filters.status !== void 0 || filters.color !== void 0 || filters.priority !== void 0 || tags !== void 0 && tags.length > 0;
|
|
30508
|
-
const totalResult = hasFilter ? await stickyList(projectRoot, {}) : result;
|
|
30509
|
-
if (!totalResult.success) {
|
|
30510
|
-
return wrapResult(totalResult, "query", "sticky", operation, startTime);
|
|
30511
|
-
}
|
|
30512
|
-
const limit = params?.limit;
|
|
30513
|
-
const offset = params?.offset;
|
|
30514
|
-
const page = paginate6(filteredStickies, limit, offset);
|
|
30515
|
-
return {
|
|
30516
|
-
meta: dispatchMeta("query", "sticky", operation, startTime),
|
|
30517
|
-
success: true,
|
|
30518
|
-
data: {
|
|
30519
|
-
stickies: page.items,
|
|
30520
|
-
total: totalResult.data?.total ?? filteredStickies.length,
|
|
30521
|
-
filtered: filteredStickies.length
|
|
30671
|
+
const result = await stickyListFiltered(
|
|
30672
|
+
projectRoot,
|
|
30673
|
+
{
|
|
30674
|
+
status: params?.status,
|
|
30675
|
+
color: params?.color,
|
|
30676
|
+
priority: params?.priority,
|
|
30677
|
+
tags: params?.tags
|
|
30522
30678
|
},
|
|
30523
|
-
|
|
30524
|
-
|
|
30679
|
+
params?.limit,
|
|
30680
|
+
params?.offset
|
|
30681
|
+
);
|
|
30682
|
+
return wrapResult(result, "query", "sticky", operation, startTime);
|
|
30525
30683
|
}
|
|
30526
30684
|
case "show": {
|
|
30527
30685
|
const stickyId = params?.stickyId;
|
|
@@ -30707,7 +30865,7 @@ function envelopeToEngineResult5(envelope) {
|
|
|
30707
30865
|
}
|
|
30708
30866
|
};
|
|
30709
30867
|
}
|
|
30710
|
-
var _tasksTypedHandler,
|
|
30868
|
+
var _tasksTypedHandler, QUERY_OPS8, MUTATE_OPS8, TasksHandler;
|
|
30711
30869
|
var init_tasks3 = __esm({
|
|
30712
30870
|
"packages/cleo/src/dispatch/domains/tasks.ts"() {
|
|
30713
30871
|
"use strict";
|
|
@@ -31046,7 +31204,7 @@ var init_tasks3 = __esm({
|
|
|
31046
31204
|
return wrapCoreResult(await taskUnclaim(projectRoot, params.taskId), "unclaim");
|
|
31047
31205
|
}
|
|
31048
31206
|
});
|
|
31049
|
-
|
|
31207
|
+
QUERY_OPS8 = /* @__PURE__ */ new Set([
|
|
31050
31208
|
"show",
|
|
31051
31209
|
"list",
|
|
31052
31210
|
"find",
|
|
@@ -31064,7 +31222,7 @@ var init_tasks3 = __esm({
|
|
|
31064
31222
|
"label.list",
|
|
31065
31223
|
"sync.links"
|
|
31066
31224
|
]);
|
|
31067
|
-
|
|
31225
|
+
MUTATE_OPS8 = /* @__PURE__ */ new Set([
|
|
31068
31226
|
"add",
|
|
31069
31227
|
"update",
|
|
31070
31228
|
"complete",
|
|
@@ -31094,7 +31252,7 @@ var init_tasks3 = __esm({
|
|
|
31094
31252
|
*/
|
|
31095
31253
|
async query(operation, params) {
|
|
31096
31254
|
const startTime = Date.now();
|
|
31097
|
-
if (!
|
|
31255
|
+
if (!QUERY_OPS8.has(operation)) {
|
|
31098
31256
|
return unsupportedOp("query", "tasks", operation, startTime);
|
|
31099
31257
|
}
|
|
31100
31258
|
if (operation === "impact" && !params?.change) {
|
|
@@ -31133,7 +31291,7 @@ var init_tasks3 = __esm({
|
|
|
31133
31291
|
*/
|
|
31134
31292
|
async mutate(operation, params) {
|
|
31135
31293
|
const startTime = Date.now();
|
|
31136
|
-
if (!
|
|
31294
|
+
if (!MUTATE_OPS8.has(operation)) {
|
|
31137
31295
|
return unsupportedOp("mutate", "tasks", operation, startTime);
|
|
31138
31296
|
}
|
|
31139
31297
|
try {
|
|
@@ -52305,6 +52463,29 @@ var fanoutCommand = defineCommand({
|
|
|
52305
52463
|
);
|
|
52306
52464
|
}
|
|
52307
52465
|
});
|
|
52466
|
+
var pruneCommand = defineCommand({
|
|
52467
|
+
meta: {
|
|
52468
|
+
name: "prune",
|
|
52469
|
+
description: "Remove stale agent worktrees (after task completion or crash)"
|
|
52470
|
+
},
|
|
52471
|
+
args: {
|
|
52472
|
+
taskId: {
|
|
52473
|
+
type: "positional",
|
|
52474
|
+
description: "Task ID whose worktree should be pruned (omit for bulk prune)",
|
|
52475
|
+
required: false
|
|
52476
|
+
}
|
|
52477
|
+
},
|
|
52478
|
+
async run({ args }) {
|
|
52479
|
+
const taskId = typeof args.taskId === "string" && args.taskId.length > 0 ? args.taskId : void 0;
|
|
52480
|
+
await dispatchFromCli(
|
|
52481
|
+
"mutate",
|
|
52482
|
+
"orchestrate",
|
|
52483
|
+
"worktree.prune",
|
|
52484
|
+
{ taskId },
|
|
52485
|
+
{ command: "orchestrate" }
|
|
52486
|
+
);
|
|
52487
|
+
}
|
|
52488
|
+
});
|
|
52308
52489
|
var conduitStatusCommand = defineCommand({
|
|
52309
52490
|
meta: { name: "conduit-status", description: "Get conduit messaging status" },
|
|
52310
52491
|
async run() {
|
|
@@ -52486,6 +52667,7 @@ var orchestrateCommand = defineCommand({
|
|
|
52486
52667
|
handoff: handoffCommand,
|
|
52487
52668
|
"spawn-execute": spawnExecuteCommand,
|
|
52488
52669
|
fanout: fanoutCommand,
|
|
52670
|
+
prune: pruneCommand,
|
|
52489
52671
|
"conduit-status": conduitStatusCommand,
|
|
52490
52672
|
"conduit-peek": conduitPeekCommand,
|
|
52491
52673
|
"conduit-start": conduitStartCommand,
|
|
@@ -58622,7 +58804,7 @@ var migrateCommand2 = defineCommand({
|
|
|
58622
58804
|
}
|
|
58623
58805
|
}
|
|
58624
58806
|
});
|
|
58625
|
-
var
|
|
58807
|
+
var pruneCommand2 = defineCommand({
|
|
58626
58808
|
meta: {
|
|
58627
58809
|
name: "prune",
|
|
58628
58810
|
description: "Prune session transcripts older than the specified duration. Dry-run by default."
|
|
@@ -58749,7 +58931,7 @@ var transcriptCommand = defineCommand({
|
|
|
58749
58931
|
scan: scanCommand,
|
|
58750
58932
|
extract: extractCommand,
|
|
58751
58933
|
migrate: migrateCommand2,
|
|
58752
|
-
prune:
|
|
58934
|
+
prune: pruneCommand2
|
|
58753
58935
|
},
|
|
58754
58936
|
async run({ cmd, rawArgs }) {
|
|
58755
58937
|
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|
|
@@ -59095,6 +59277,10 @@ var verifyCommand2 = defineCommand({
|
|
|
59095
59277
|
explain: {
|
|
59096
59278
|
type: "boolean",
|
|
59097
59279
|
description: "Enrich read-only view with per-gate evidence breakdown, re-validation status, and blockers[] preventing `cleo complete` (T1013 / ADR-051)."
|
|
59280
|
+
},
|
|
59281
|
+
"shared-evidence": {
|
|
59282
|
+
type: "boolean",
|
|
59283
|
+
description: "Acknowledge that the same evidence atom is applied to >3 distinct tasks in this session (T1502 / ADR-059). Without this flag, such reuse triggers a warning; in strict mode (CLEO_STRICT_EVIDENCE=1) it is a hard reject."
|
|
59098
59284
|
}
|
|
59099
59285
|
},
|
|
59100
59286
|
async run({ args, cmd }) {
|
|
@@ -59116,7 +59302,8 @@ var verifyCommand2 = defineCommand({
|
|
|
59116
59302
|
agent: args.agent,
|
|
59117
59303
|
all: args.all,
|
|
59118
59304
|
reset: args.reset,
|
|
59119
|
-
evidence: args.evidence
|
|
59305
|
+
evidence: args.evidence,
|
|
59306
|
+
sharedEvidence: args["shared-evidence"] ?? false
|
|
59120
59307
|
},
|
|
59121
59308
|
{ command: "verify" }
|
|
59122
59309
|
);
|