@cleocode/contracts 2026.5.92 → 2026.5.94
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/__tests__/docs-taxonomy.test.d.ts +16 -0
- package/dist/__tests__/docs-taxonomy.test.d.ts.map +1 -0
- package/dist/__tests__/docs-taxonomy.test.js +404 -0
- package/dist/__tests__/docs-taxonomy.test.js.map +1 -0
- package/dist/cli-category.d.ts +24 -0
- package/dist/cli-category.d.ts.map +1 -0
- package/dist/cli-category.js +32 -0
- package/dist/cli-category.js.map +1 -0
- package/dist/docs-taxonomy.d.ts +286 -0
- package/dist/docs-taxonomy.d.ts.map +1 -0
- package/dist/docs-taxonomy.js +489 -0
- package/dist/docs-taxonomy.js.map +1 -0
- package/dist/doctor.d.ts +120 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +16 -0
- package/dist/doctor.js.map +1 -0
- package/dist/exit-codes.d.ts +29 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +29 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/operations/docs.d.ts +89 -11
- package/dist/operations/docs.d.ts.map +1 -1
- package/dist/operations/docs.js +19 -12
- package/dist/operations/docs.js.map +1 -1
- package/dist/operations/release.d.ts +0 -25
- package/dist/operations/release.d.ts.map +1 -1
- package/dist/operations/session.d.ts +66 -0
- package/dist/operations/session.d.ts.map +1 -1
- package/dist/operations/tasks.d.ts +64 -0
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/validate.d.ts +32 -0
- package/dist/operations/validate.d.ts.map +1 -1
- package/dist/release/evidence-atoms.d.ts +37 -1
- package/dist/release/evidence-atoms.d.ts.map +1 -1
- package/dist/release/evidence-atoms.js +22 -0
- package/dist/release/evidence-atoms.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/docs-taxonomy.test.ts +465 -0
- package/src/cli-category.ts +52 -0
- package/src/docs-taxonomy.ts +682 -0
- package/src/doctor.ts +130 -0
- package/src/exit-codes.ts +30 -0
- package/src/index.ts +36 -2
- package/src/operations/docs.ts +92 -18
- package/src/operations/release.ts +0 -28
- package/src/operations/session.ts +71 -0
- package/src/operations/tasks.ts +67 -0
- package/src/operations/validate.ts +34 -0
- package/src/release/evidence-atoms.ts +38 -0
package/src/doctor.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor domain contracts — types for `cleo doctor` worktree-orphan audit/prune.
|
|
3
|
+
*
|
|
4
|
+
* These types describe orphan `.cleo/` directories left behind under
|
|
5
|
+
* `<projectRoot>/.claude/worktrees/` by the T9550/T9580 SSoT bug (fixed in
|
|
6
|
+
* v2026.5.83) and the schema for the audit JSONL line written per prune.
|
|
7
|
+
*
|
|
8
|
+
* Consumed by:
|
|
9
|
+
* - `packages/core/src/doctor/worktree-orphans.ts` (scan + prune primitives)
|
|
10
|
+
* - `packages/cleo/src/cli/commands/doctor.ts` (CLI flags)
|
|
11
|
+
*
|
|
12
|
+
* @task T9790
|
|
13
|
+
* @epic T9790
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* One orphan `.cleo/` directory discovered under
|
|
18
|
+
* `<projectRoot>/.claude/worktrees/`.
|
|
19
|
+
*
|
|
20
|
+
* Worktrees are nested 1-3 levels deep — examples:
|
|
21
|
+
* - `<projectRoot>/.claude/worktrees/agent-X/.cleo/` (depth 1)
|
|
22
|
+
* - `<projectRoot>/.claude/worktrees/agent-X/T9220/.cleo/` (depth 2)
|
|
23
|
+
*
|
|
24
|
+
* Each entry carries full provenance so the operator can decide whether
|
|
25
|
+
* the orphan represents lost work before pruning.
|
|
26
|
+
*/
|
|
27
|
+
export interface OrphanEntry {
|
|
28
|
+
/**
|
|
29
|
+
* The worktree root that contains the orphan — the first directory under
|
|
30
|
+
* `.claude/worktrees/` (e.g. `<projectRoot>/.claude/worktrees/agent-X`).
|
|
31
|
+
* Used as the boundary that `pruneWorktreeOrphans` validates against.
|
|
32
|
+
*/
|
|
33
|
+
worktreePath: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Absolute path to the orphan `.cleo/` directory itself. Always lives
|
|
37
|
+
* under `worktreePath` (the security check rejects anything that doesn't).
|
|
38
|
+
*/
|
|
39
|
+
orphanPath: string;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* List of `tasks.db`, `brain.db`, `nexus.db`, or `config.json` paths
|
|
43
|
+
* found inside the orphan. Empty array means the orphan exists but is
|
|
44
|
+
* structurally empty (still pruned — it shouldn't be there at all).
|
|
45
|
+
*/
|
|
46
|
+
dbFiles: string[];
|
|
47
|
+
|
|
48
|
+
/** Total byte size of the orphan tree (sum of regular file sizes). */
|
|
49
|
+
sizeBytes: number;
|
|
50
|
+
|
|
51
|
+
/** ISO-8601 timestamp of the most recent file modification under the orphan. */
|
|
52
|
+
lastModifiedAt: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Seconds since `lastModifiedAt` (relative to scan time). Surfaces "stale
|
|
56
|
+
* vs recent" without forcing the caller to compute date math.
|
|
57
|
+
*/
|
|
58
|
+
ageSeconds: number;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* `true` when the orphan contains more than just stray DB files — e.g. a
|
|
62
|
+
* full duplicate of `adrs/`, `agent-outputs/`, `rcasd/`, etc. These need
|
|
63
|
+
* heightened operator review before pruning.
|
|
64
|
+
*/
|
|
65
|
+
isFullDuplicate: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Result of one prune operation. Reports the archive location, the per-entry
|
|
70
|
+
* outcome, and any entries rejected by the security gate.
|
|
71
|
+
*/
|
|
72
|
+
export interface PruneResult {
|
|
73
|
+
/**
|
|
74
|
+
* Absolute path to the `.tar.gz` archive written before any deletion.
|
|
75
|
+
* `null` only when `dryRun: true` AND no archive was produced.
|
|
76
|
+
*/
|
|
77
|
+
archivePath: string | null;
|
|
78
|
+
|
|
79
|
+
/** Whether this was a dry run (no archive, no rm, no audit-log line). */
|
|
80
|
+
dryRun: boolean;
|
|
81
|
+
|
|
82
|
+
/** Entries that were successfully pruned (or would be in dry-run mode). */
|
|
83
|
+
pruned: OrphanEntry[];
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Entries that failed validation and were skipped. The `reason` is a
|
|
87
|
+
* stable machine-readable code (e.g. `path-outside-worktrees-root`,
|
|
88
|
+
* `path-not-found`, `rm-failed`).
|
|
89
|
+
*/
|
|
90
|
+
rejected: Array<{ entry: OrphanEntry; reason: string }>;
|
|
91
|
+
|
|
92
|
+
/** Total bytes archived (sum of `pruned[].sizeBytes`). */
|
|
93
|
+
totalSizeBytes: number;
|
|
94
|
+
|
|
95
|
+
/** ISO-8601 timestamp the prune completed. */
|
|
96
|
+
prunedAt: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* One line appended to `.cleo/audit/worktree-prune.jsonl` per prune
|
|
101
|
+
* operation. Extends the existing audit-log schema (timestamp +
|
|
102
|
+
* worktreePath + action + agent) with the orphan-specific fields needed
|
|
103
|
+
* to reconstruct what was removed.
|
|
104
|
+
*
|
|
105
|
+
* Existing fields preserved for schema continuity:
|
|
106
|
+
* - `timestamp`, `worktreePath`, `action`, `agent`
|
|
107
|
+
*
|
|
108
|
+
* New fields for orphan prune:
|
|
109
|
+
* - `orphanPath`, `sizeBytes`, `dbFileCount`, `archivePath`, `dryRun`
|
|
110
|
+
*/
|
|
111
|
+
export interface PruneAuditEntry {
|
|
112
|
+
/** ISO-8601 timestamp. */
|
|
113
|
+
timestamp: string;
|
|
114
|
+
/** Worktree root that contained the orphan. */
|
|
115
|
+
worktreePath: string;
|
|
116
|
+
/** Absolute path to the orphan `.cleo/` directory removed. */
|
|
117
|
+
orphanPath: string;
|
|
118
|
+
/** Action code — fixed to `'prune-worktree-orphan'` for this flow. */
|
|
119
|
+
action: 'prune-worktree-orphan';
|
|
120
|
+
/** Always `'cleo'` — written by `cleo doctor`. */
|
|
121
|
+
agent: 'cleo';
|
|
122
|
+
/** Byte size of the pruned tree. */
|
|
123
|
+
sizeBytes: number;
|
|
124
|
+
/** Number of DB files found in the orphan (informational). */
|
|
125
|
+
dbFileCount: number;
|
|
126
|
+
/** Absolute path to the archive. `null` only on dry-run lines. */
|
|
127
|
+
archivePath: string | null;
|
|
128
|
+
/** Whether this entry represents a dry-run plan (no actual removal). */
|
|
129
|
+
dryRun: boolean;
|
|
130
|
+
}
|
package/src/exit-codes.ts
CHANGED
|
@@ -244,6 +244,17 @@ export const E_DIRTY_TREE = 'E_DIRTY_TREE' as const;
|
|
|
244
244
|
export const E_EPIC_EMPTY = 'E_EPIC_EMPTY' as const;
|
|
245
245
|
/** Epic referenced by `--epic` does not exist (R-021). Exit code 10. */
|
|
246
246
|
export const E_EPIC_NOT_FOUND = 'E_EPIC_NOT_FOUND' as const;
|
|
247
|
+
/**
|
|
248
|
+
* Leaf-Epic-as-Task ship (`--epic <id>` where the Epic has zero non-cancelled
|
|
249
|
+
* child tasks) was attempted but the Epic itself carries zero ADR-051 evidence
|
|
250
|
+
* atoms. Per ADR-073 the leaf-Epic-as-PR pattern is canonical for atomic ships,
|
|
251
|
+
* but the Epic still needs evidence (commit:sha, files, pr:<num>, etc.) to
|
|
252
|
+
* be promoted into a release. Exit code 83. `error.details.epicId` reports
|
|
253
|
+
* the offending Epic. `error.details.fix` points at `cleo verify`.
|
|
254
|
+
*
|
|
255
|
+
* @task T9838
|
|
256
|
+
*/
|
|
257
|
+
export const E_EPIC_EMPTY_LEAF_NO_EVIDENCE = 'E_EPIC_EMPTY_LEAF_NO_EVIDENCE' as const;
|
|
247
258
|
/** Channel + version scheme are incompatible (R-022). Exit code 6. */
|
|
248
259
|
export const E_CHANNEL_MISMATCH = 'E_CHANNEL_MISMATCH' as const;
|
|
249
260
|
/**
|
|
@@ -280,6 +291,25 @@ export const E_GH_NOT_AUTHENTICATED = 'E_GH_NOT_AUTHENTICATED' as const;
|
|
|
280
291
|
*/
|
|
281
292
|
export const E_WORKFLOW_NOT_FOUND = 'E_WORKFLOW_NOT_FOUND' as const;
|
|
282
293
|
|
|
294
|
+
/**
|
|
295
|
+
* E_WRITE_CONTENTION — Persistent SQLITE_BUSY after exhausting application-level
|
|
296
|
+
* retry. Emitted by {@link withWriteRetry} (in `@cleocode/core`'s
|
|
297
|
+
* `store/with-retry.ts`) when a SQLite write transaction fails 4 consecutive
|
|
298
|
+
* attempts with `SQLITE_BUSY: database is locked` despite the engine-level
|
|
299
|
+
* `busy_timeout=5000ms` pragma.
|
|
300
|
+
*
|
|
301
|
+
* **Recovery**: retry the operation after a brief delay (the contended writer
|
|
302
|
+
* usually commits within 1-2 seconds). If the error reoccurs reliably, suspect
|
|
303
|
+
* a long-running writer holding a RESERVED lock — inspect with
|
|
304
|
+
* `sqlite3 .cleo/tasks.db "PRAGMA wal_checkpoint(FULL); SELECT * FROM sqlite_lock;"`.
|
|
305
|
+
*
|
|
306
|
+
* Maps to {@link ExitCode.LOCK_TIMEOUT} (7) at the CLI boundary.
|
|
307
|
+
*
|
|
308
|
+
* @bug gh-391 — parallel `cleo update --add-labels` losing ~50% of writes.
|
|
309
|
+
* @task T9839
|
|
310
|
+
*/
|
|
311
|
+
export const E_WRITE_CONTENTION = 'E_WRITE_CONTENTION' as const;
|
|
312
|
+
|
|
283
313
|
/** Check if an exit code represents an error (1-99). */
|
|
284
314
|
export function isErrorCode(code: ExitCode): boolean {
|
|
285
315
|
return code >= 1 && code < 100;
|
package/src/index.ts
CHANGED
|
@@ -180,6 +180,9 @@ export type { AdapterCapabilities } from './capabilities.js';
|
|
|
180
180
|
// === Changesets (CLEO-native task-anchored DSL — T9738) ===
|
|
181
181
|
export type { ChangesetEntry, ChangesetKind } from './changesets.js';
|
|
182
182
|
export { CHANGESET_KINDS, ChangesetEntrySchema } from './changesets.js';
|
|
183
|
+
// === CLI Category Types (help renderer grouping SSoT) ===
|
|
184
|
+
export type { CliCategory } from './cli-category.js';
|
|
185
|
+
export { CLI_CATEGORY_ORDER } from './cli-category.js';
|
|
183
186
|
// === Code Symbol Types (tree-sitter AST) ===
|
|
184
187
|
export type {
|
|
185
188
|
BatchParseResult,
|
|
@@ -277,6 +280,22 @@ export type {
|
|
|
277
280
|
StoreDocParams,
|
|
278
281
|
StoreDocResult,
|
|
279
282
|
} from './docs-accessor.js';
|
|
283
|
+
// === Canonical Doc-Kind Taxonomy Registry (T9788) ===
|
|
284
|
+
export type {
|
|
285
|
+
BuiltinDocKind,
|
|
286
|
+
DocKindConfigFile,
|
|
287
|
+
DocKindExtensionConfig,
|
|
288
|
+
DocKindMetadata,
|
|
289
|
+
SlugValidationResult,
|
|
290
|
+
} from './docs-taxonomy.js';
|
|
291
|
+
export {
|
|
292
|
+
BUILTIN_DOC_KIND_VALUES,
|
|
293
|
+
BUILTIN_DOC_KINDS,
|
|
294
|
+
DocKindConfigError,
|
|
295
|
+
DocKindRegistry,
|
|
296
|
+
} from './docs-taxonomy.js';
|
|
297
|
+
// === Doctor: Worktree-Orphan Audit + Prune Types (T9790) ===
|
|
298
|
+
export type { OrphanEntry, PruneAuditEntry, PruneResult } from './doctor.js';
|
|
280
299
|
export type {
|
|
281
300
|
EngineErrorPayload,
|
|
282
301
|
EngineFailure,
|
|
@@ -339,6 +358,7 @@ export {
|
|
|
339
358
|
E_CHANNEL_MISMATCH,
|
|
340
359
|
E_DIRTY_TREE,
|
|
341
360
|
E_EPIC_EMPTY,
|
|
361
|
+
E_EPIC_EMPTY_LEAF_NO_EVIDENCE,
|
|
342
362
|
E_EPIC_NOT_FOUND,
|
|
343
363
|
E_EVIDENCE_INSUFFICIENT,
|
|
344
364
|
// SPEC-T9345 release pipeline v2 error code names (T9530)
|
|
@@ -347,6 +367,8 @@ export {
|
|
|
347
367
|
E_PLAN_NOT_FOUND,
|
|
348
368
|
E_RELEASE_PLAN_INVALID,
|
|
349
369
|
E_WORKFLOW_NOT_FOUND,
|
|
370
|
+
// gh#391 — application-level SQLITE_BUSY retry exhaustion (T9839)
|
|
371
|
+
E_WRITE_CONTENTION,
|
|
350
372
|
ExitCode,
|
|
351
373
|
getExitCodeName,
|
|
352
374
|
isErrorCode,
|
|
@@ -993,6 +1015,9 @@ export type {
|
|
|
993
1015
|
SessionGcResult,
|
|
994
1016
|
SessionHandoffShowParams,
|
|
995
1017
|
SessionHandoffShowResult,
|
|
1018
|
+
SessionLintParams,
|
|
1019
|
+
SessionLintResult,
|
|
1020
|
+
SessionLintViolation,
|
|
996
1021
|
SessionListParams,
|
|
997
1022
|
SessionListResult,
|
|
998
1023
|
SessionOps,
|
|
@@ -1015,6 +1040,8 @@ export type {
|
|
|
1015
1040
|
DepGraphIssue,
|
|
1016
1041
|
DepsTreeEdge,
|
|
1017
1042
|
DepsTreeNode,
|
|
1043
|
+
TasksAddBatchParams,
|
|
1044
|
+
TasksAddBatchResult,
|
|
1018
1045
|
TasksAddParams,
|
|
1019
1046
|
TasksAddResult,
|
|
1020
1047
|
TasksAnalyzeQueryParams,
|
|
@@ -1105,6 +1132,8 @@ export type {
|
|
|
1105
1132
|
ComplianceMetrics,
|
|
1106
1133
|
ValidateArchiveStatsParams,
|
|
1107
1134
|
ValidateArchiveStatsResult,
|
|
1135
|
+
ValidateCanonDocsParams,
|
|
1136
|
+
ValidateCanonDocsResult,
|
|
1108
1137
|
ValidateCanonParams,
|
|
1109
1138
|
ValidateCanonResult,
|
|
1110
1139
|
ValidateChainParams,
|
|
@@ -1247,13 +1276,18 @@ export type {
|
|
|
1247
1276
|
export type { AdapterPathProvider } from './provider-paths.js';
|
|
1248
1277
|
// === Release Channel ===
|
|
1249
1278
|
export type { ChannelValidationResult, ReleaseChannel } from './release/channel.js';
|
|
1250
|
-
// === Release Evidence Atoms (T9764) ===
|
|
1251
|
-
export type {
|
|
1279
|
+
// === Release Evidence Atoms (T9764 + T9838) ===
|
|
1280
|
+
export type {
|
|
1281
|
+
GhPrViewPayload,
|
|
1282
|
+
ParsedPrEvidenceAtom,
|
|
1283
|
+
PrEvidenceStateModifier,
|
|
1284
|
+
} from './release/evidence-atoms.js';
|
|
1252
1285
|
export {
|
|
1253
1286
|
ghPrViewSchema,
|
|
1254
1287
|
PR_REQUIRED_WORKFLOWS,
|
|
1255
1288
|
PR_REQUIRED_WORKFLOWS_ENV_VAR,
|
|
1256
1289
|
parsedPrEvidenceAtomSchema,
|
|
1290
|
+
prEvidenceStateModifierSchema,
|
|
1257
1291
|
} from './release/evidence-atoms.js';
|
|
1258
1292
|
// === Release GitHub PR ===
|
|
1259
1293
|
export type {
|
package/src/operations/docs.ts
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import type { AttachmentKind } from '../attachment.js';
|
|
32
|
+
import { BUILTIN_DOC_KIND_VALUES, type BuiltinDocKind } from '../docs-taxonomy.js';
|
|
32
33
|
|
|
33
34
|
// ============================================================================
|
|
34
35
|
// Shared Attachment Types (API wire format)
|
|
@@ -54,28 +55,32 @@ export type { AttachmentKind } from '../attachment.js';
|
|
|
54
55
|
/**
|
|
55
56
|
* Allowed values for the `--type` taxonomy on `cleo docs add`.
|
|
56
57
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* As of T9788 this is derived from the canonical {@link BUILTIN_DOC_KIND_VALUES}
|
|
59
|
+
* in `docs-taxonomy.ts` — adding a kind there automatically widens this set
|
|
60
|
+
* without a duplicate edit here.
|
|
61
|
+
*
|
|
62
|
+
* Project-level extensions registered through `.cleo/docs-config.json` are
|
|
63
|
+
* NOT included in this constant (they are runtime-only, since the
|
|
64
|
+
* compile-time union must stay closed). Use {@link DocKindRegistry.list}
|
|
65
|
+
* to enumerate built-ins plus extensions at runtime.
|
|
61
66
|
*
|
|
62
67
|
* @task T9637 (T-DOCS-SLUG-2)
|
|
68
|
+
* @task T9788 (E-DOCS-TAXONOMY-V2 — registry consolidation)
|
|
63
69
|
*/
|
|
64
|
-
export const DOCS_TYPE_VALUES =
|
|
65
|
-
|
|
66
|
-
'adr',
|
|
67
|
-
'research',
|
|
68
|
-
'handoff',
|
|
69
|
-
'note',
|
|
70
|
-
'llm-readme',
|
|
71
|
-
] as const;
|
|
70
|
+
export const DOCS_TYPE_VALUES: ReadonlyArray<BuiltinDocKind> =
|
|
71
|
+
BUILTIN_DOC_KIND_VALUES as ReadonlyArray<BuiltinDocKind>;
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Closed-set type alias for {@link DOCS_TYPE_VALUES}.
|
|
75
75
|
*
|
|
76
|
+
* As of T9788 this aliases {@link BuiltinDocKind} from the canonical
|
|
77
|
+
* registry — the union widens automatically when a new built-in kind
|
|
78
|
+
* is added to {@link BUILTIN_DOC_KINDS}.
|
|
79
|
+
*
|
|
76
80
|
* @task T9637
|
|
81
|
+
* @task T9788
|
|
77
82
|
*/
|
|
78
|
-
export type DocsType =
|
|
83
|
+
export type DocsType = BuiltinDocKind;
|
|
79
84
|
|
|
80
85
|
/**
|
|
81
86
|
* Flattened wire-format attachment row returned by docs query operations.
|
|
@@ -169,16 +174,38 @@ export interface AttachmentRecord {
|
|
|
169
174
|
// docs.list — list attachments for an owner
|
|
170
175
|
// --------------------------------------------------------------------------
|
|
171
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Sort key for `docs.list` results.
|
|
179
|
+
*
|
|
180
|
+
* - `newest` — descending by `createdAt` (default — most recent first).
|
|
181
|
+
* - `sha` — ascending by `sha256` (stable lexicographic).
|
|
182
|
+
* - `slug` — ascending by `slug`; entries without a slug sort last.
|
|
183
|
+
*
|
|
184
|
+
* @task T9792
|
|
185
|
+
*/
|
|
186
|
+
export type DocsListOrderBy = 'newest' | 'sha' | 'slug';
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Default maximum number of rows returned by `docs.list` when the caller
|
|
190
|
+
* does not pass an explicit `limit`. Mirrored on the CLI flag default so the
|
|
191
|
+
* dispatch and CLI surfaces agree on the browsing window.
|
|
192
|
+
*
|
|
193
|
+
* @task T9792
|
|
194
|
+
*/
|
|
195
|
+
export const DOCS_LIST_DEFAULT_LIMIT = 50;
|
|
196
|
+
|
|
172
197
|
/**
|
|
173
198
|
* Parameters for `docs.list`.
|
|
174
199
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* mode and matches the
|
|
200
|
+
* Scope is auto-promoted to whole-project when no owner-scope flag is set
|
|
201
|
+
* (T9792). Pre-T9792 callers MUST still pass `project: true` explicitly to
|
|
202
|
+
* stay forward-compatible — the auto-promote happens at the CLI layer.
|
|
203
|
+
* `type` is an optional filter applicable to every mode and matches the
|
|
204
|
+
* {@link DocsType} taxonomy exactly.
|
|
179
205
|
*
|
|
180
206
|
* @task T9637 (T-DOCS-SLUG-2 — `type` filter)
|
|
181
207
|
* @task T9638 (T-DOCS-SLUG-3 — `project` scope)
|
|
208
|
+
* @task T9792 (E-DOCS-LIST-UX-FIX — auto-promote project scope + limit + orderBy)
|
|
182
209
|
*/
|
|
183
210
|
export interface DocsListParams {
|
|
184
211
|
/** Task identifier to list attachments for. */
|
|
@@ -199,6 +226,20 @@ export interface DocsListParams {
|
|
|
199
226
|
* @task T9637
|
|
200
227
|
*/
|
|
201
228
|
type?: DocsType;
|
|
229
|
+
/**
|
|
230
|
+
* Maximum number of rows to return. Defaults to
|
|
231
|
+
* {@link DOCS_LIST_DEFAULT_LIMIT} when omitted. Values `<= 0` are treated
|
|
232
|
+
* as "no limit" so agents can opt-in to the full result set explicitly.
|
|
233
|
+
*
|
|
234
|
+
* @task T9792
|
|
235
|
+
*/
|
|
236
|
+
limit?: number;
|
|
237
|
+
/**
|
|
238
|
+
* Sort key for the returned rows. Defaults to `newest` when omitted.
|
|
239
|
+
*
|
|
240
|
+
* @task T9792
|
|
241
|
+
*/
|
|
242
|
+
orderBy?: DocsListOrderBy;
|
|
202
243
|
}
|
|
203
244
|
|
|
204
245
|
/**
|
|
@@ -218,8 +259,41 @@ export interface DocsListResult {
|
|
|
218
259
|
project?: boolean;
|
|
219
260
|
/** Type taxonomy filter, echoed back from the request when provided. */
|
|
220
261
|
type?: DocsType;
|
|
221
|
-
/** Count of attachments for this owner. */
|
|
262
|
+
/** Count of attachments for this owner (after limit + filters). */
|
|
222
263
|
count: number;
|
|
264
|
+
/**
|
|
265
|
+
* Total number of attachments matching the scope + filters BEFORE the
|
|
266
|
+
* `limit` window was applied. Only emitted when `limit` truncated the
|
|
267
|
+
* result set so consumers can distinguish "fewer than limit" from
|
|
268
|
+
* "limit truncated".
|
|
269
|
+
*
|
|
270
|
+
* @task T9792
|
|
271
|
+
*/
|
|
272
|
+
totalCount?: number;
|
|
273
|
+
/**
|
|
274
|
+
* Effective limit applied to this response. Mirrored from the request
|
|
275
|
+
* (or {@link DOCS_LIST_DEFAULT_LIMIT} when the request did not set one)
|
|
276
|
+
* so consumers can paginate without re-deriving the default.
|
|
277
|
+
*
|
|
278
|
+
* @task T9792
|
|
279
|
+
*/
|
|
280
|
+
limit?: number;
|
|
281
|
+
/**
|
|
282
|
+
* Effective sort key applied to this response. Mirrored from the request
|
|
283
|
+
* (or `"newest"` when the request did not set one).
|
|
284
|
+
*
|
|
285
|
+
* @task T9792
|
|
286
|
+
*/
|
|
287
|
+
orderBy?: DocsListOrderBy;
|
|
288
|
+
/**
|
|
289
|
+
* Optional human-readable hint surfaced when a default behaviour kicked
|
|
290
|
+
* in (e.g. project scope auto-promoted because no scope was passed). The
|
|
291
|
+
* CLI surfaces this through `meta.hint` so JSON consumers can detect that
|
|
292
|
+
* a narrower invocation may have been intended.
|
|
293
|
+
*
|
|
294
|
+
* @task T9792
|
|
295
|
+
*/
|
|
296
|
+
hint?: string;
|
|
223
297
|
/** Attachment metadata array. */
|
|
224
298
|
attachments: DocsAttachmentRow[];
|
|
225
299
|
/** Current attachment backend in use. */
|
|
@@ -16,14 +16,6 @@ export interface ReleaseGate {
|
|
|
16
16
|
reason?: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export interface ChangelogSection {
|
|
20
|
-
type: 'feat' | 'fix' | 'docs' | 'test' | 'refactor' | 'chore';
|
|
21
|
-
entries: Array<{
|
|
22
|
-
taskId: string;
|
|
23
|
-
message: string;
|
|
24
|
-
}>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
19
|
/**
|
|
28
20
|
* Mutate Operations
|
|
29
21
|
*/
|
|
@@ -65,26 +57,6 @@ export interface ReleasePrepareResult {
|
|
|
65
57
|
taskCount: number;
|
|
66
58
|
}
|
|
67
59
|
|
|
68
|
-
// release.changelog
|
|
69
|
-
/** Parameters for `release.changelog`. @task T963 */
|
|
70
|
-
export interface ReleaseChangelogParams {
|
|
71
|
-
/** Version to build the changelog for (must match an existing manifest). @task T963 */
|
|
72
|
-
version: string;
|
|
73
|
-
/** Filter emitted sections. @task T963 */
|
|
74
|
-
sections?: Array<'feat' | 'fix' | 'docs' | 'test' | 'refactor' | 'chore'>;
|
|
75
|
-
}
|
|
76
|
-
/** Result of `release.changelog`. @task T963 */
|
|
77
|
-
export interface ReleaseChangelogResult {
|
|
78
|
-
/** Version. @task T963 */
|
|
79
|
-
version: string;
|
|
80
|
-
/** Rendered changelog content (Markdown). @task T963 */
|
|
81
|
-
content: string;
|
|
82
|
-
/** Grouped changelog sections. @task T963 */
|
|
83
|
-
sections: ChangelogSection[];
|
|
84
|
-
/** Count of commits aggregated. @task T963 */
|
|
85
|
-
commitCount: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
60
|
// release.commit
|
|
89
61
|
/** Parameters for `release.commit`. @task T963 */
|
|
90
62
|
export interface ReleaseCommitParams {
|
|
@@ -587,6 +587,76 @@ export interface SessionRecordAssumptionResult {
|
|
|
587
587
|
timestamp: string;
|
|
588
588
|
}
|
|
589
589
|
|
|
590
|
+
// session.lint — agent-accountability harness (T9797)
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Parameters for `session.lint`.
|
|
594
|
+
*
|
|
595
|
+
* Scans a Claude Code-style session transcript (`*.jsonl`) for raw
|
|
596
|
+
* markdown writes that bypass the docs SSoT. Flags any tool call whose
|
|
597
|
+
* `file_path` lands under a `rawMdPaths` entry whose owning DocKind has
|
|
598
|
+
* `rawMdAllowed: false` in `.cleo/canon.yml`.
|
|
599
|
+
*
|
|
600
|
+
* @task T9797
|
|
601
|
+
*/
|
|
602
|
+
export interface SessionLintParams {
|
|
603
|
+
/**
|
|
604
|
+
* Absolute path to the `.jsonl` transcript to scan. Required.
|
|
605
|
+
*/
|
|
606
|
+
transcript: string;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* One violation surfaced by `session.lint`.
|
|
611
|
+
*
|
|
612
|
+
* Mirrors `CanonLintViolation` from
|
|
613
|
+
* `packages/core/src/session/canon-lint.ts` (the SDK-level engine).
|
|
614
|
+
*
|
|
615
|
+
* @task T9797
|
|
616
|
+
*/
|
|
617
|
+
export interface SessionLintViolation {
|
|
618
|
+
/** Session id derived from the transcript filename. */
|
|
619
|
+
sessionId: string;
|
|
620
|
+
/** Anthropic `tool_use.id` (e.g. `toolu_01ABC...`). May be empty. */
|
|
621
|
+
toolUseId: string;
|
|
622
|
+
/** Tool name — `Write`, `Edit`, or `MultiEdit`. */
|
|
623
|
+
tool: string;
|
|
624
|
+
/** Repo-relative path the agent attempted to write. */
|
|
625
|
+
path: string;
|
|
626
|
+
/** Owning DocKind id (e.g. `adr`, `note`). */
|
|
627
|
+
docKind: string;
|
|
628
|
+
/** Matching `rawMdPaths` entry (e.g. `.cleo/adrs/`). */
|
|
629
|
+
matchedPath: string;
|
|
630
|
+
/** Categorical reason — always `'raw-md-canonical'` today. */
|
|
631
|
+
kind: 'raw-md-canonical';
|
|
632
|
+
/** First 200 chars of the violating content. */
|
|
633
|
+
evidence: string;
|
|
634
|
+
/** Suggested fix command. */
|
|
635
|
+
fix: string;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Result of `session.lint`.
|
|
640
|
+
*
|
|
641
|
+
* @task T9797
|
|
642
|
+
*/
|
|
643
|
+
export interface SessionLintResult {
|
|
644
|
+
/** Absolute transcript path that was scanned. */
|
|
645
|
+
transcriptPath: string;
|
|
646
|
+
/** Session id derived from the transcript filename. */
|
|
647
|
+
sessionId: string;
|
|
648
|
+
/** True when no violations were flagged. */
|
|
649
|
+
passed: boolean;
|
|
650
|
+
/** Number of `Write`/`Edit`/`MultiEdit` tool calls inspected. */
|
|
651
|
+
scanned: number;
|
|
652
|
+
/** Violations in transcript order. Empty when `passed === true`. */
|
|
653
|
+
violations: SessionLintViolation[];
|
|
654
|
+
/** Non-fatal warnings (e.g. JSON parse failures on isolated lines). */
|
|
655
|
+
warnings: string[];
|
|
656
|
+
/** `'enforced'` when canon.yml present, `'no-canon'` when missing. */
|
|
657
|
+
mode: 'enforced' | 'no-canon';
|
|
658
|
+
}
|
|
659
|
+
|
|
590
660
|
// ---------------------------------------------------------------------------
|
|
591
661
|
// Typed operation record (Wave D adapter — T975)
|
|
592
662
|
// ---------------------------------------------------------------------------
|
|
@@ -619,4 +689,5 @@ export type SessionOps = {
|
|
|
619
689
|
SessionRecordAssumptionParams,
|
|
620
690
|
SessionRecordAssumptionResult,
|
|
621
691
|
];
|
|
692
|
+
readonly lint: readonly [SessionLintParams, SessionLintResult];
|
|
622
693
|
};
|
package/src/operations/tasks.ts
CHANGED
|
@@ -524,6 +524,7 @@ export interface TasksCancelParams {
|
|
|
524
524
|
* Result of `tasks.cancel` — cancellation confirmation.
|
|
525
525
|
*
|
|
526
526
|
* @task T1703
|
|
527
|
+
* @task T9838 (idempotency — `alreadyCancelled` returned when re-cancelling)
|
|
527
528
|
*/
|
|
528
529
|
export interface TasksCancelResult {
|
|
529
530
|
/** The task ID that was cancelled. */
|
|
@@ -534,6 +535,14 @@ export interface TasksCancelResult {
|
|
|
534
535
|
reason?: string;
|
|
535
536
|
/** ISO 8601 timestamp of cancellation. */
|
|
536
537
|
cancelledAt: string;
|
|
538
|
+
/**
|
|
539
|
+
* True when the task was already cancelled before this call — the
|
|
540
|
+
* operation is a no-op and the response reflects the pre-existing
|
|
541
|
+
* cancellation state. Idempotent re-cancellation (T9838).
|
|
542
|
+
*
|
|
543
|
+
* @defaultValue undefined
|
|
544
|
+
*/
|
|
545
|
+
alreadyCancelled?: boolean;
|
|
537
546
|
}
|
|
538
547
|
|
|
539
548
|
// tasks.restore (with from routing: done → reopen, archived → unarchive)
|
|
@@ -653,6 +662,63 @@ export interface TasksRelatesRemoveResult {
|
|
|
653
662
|
removed: boolean;
|
|
654
663
|
}
|
|
655
664
|
|
|
665
|
+
// tasks.add-batch (atomic multi-task insert)
|
|
666
|
+
/**
|
|
667
|
+
* Parameters for `tasks.add-batch`.
|
|
668
|
+
*
|
|
669
|
+
* Wraps N `tasks.add` inserts in a single transaction; any failure rolls
|
|
670
|
+
* back ALL inserts. Closes the partial-batch bug in the CLI `add-batch`
|
|
671
|
+
* command (T9813 / T9814).
|
|
672
|
+
*
|
|
673
|
+
* @task T9814
|
|
674
|
+
*/
|
|
675
|
+
export interface TasksAddBatchParams {
|
|
676
|
+
/**
|
|
677
|
+
* Array of task specs to insert. Must be non-empty.
|
|
678
|
+
* Each spec accepts the same fields as `tasks.add` (except `dryRun`
|
|
679
|
+
* which is hoisted to the batch level).
|
|
680
|
+
*/
|
|
681
|
+
tasks: Array<{
|
|
682
|
+
title: string;
|
|
683
|
+
description?: string;
|
|
684
|
+
parent?: string;
|
|
685
|
+
depends?: string[];
|
|
686
|
+
priority?: string;
|
|
687
|
+
labels?: string[];
|
|
688
|
+
type?: string; // SSoT-EXEMPT:kind≠type — 'type' is hierarchy(epic|task|subtask), 'kind' is intent(work|bug|...) — separate axes T944
|
|
689
|
+
acceptance?: string[];
|
|
690
|
+
phase?: string;
|
|
691
|
+
size?: string;
|
|
692
|
+
notes?: string;
|
|
693
|
+
files?: string[];
|
|
694
|
+
kind?: string;
|
|
695
|
+
scope?: string;
|
|
696
|
+
severity?: string;
|
|
697
|
+
forceDuplicate?: boolean;
|
|
698
|
+
}>;
|
|
699
|
+
/** Optional default parent ID applied when a task spec omits `parent`. */
|
|
700
|
+
defaultParent?: string;
|
|
701
|
+
/**
|
|
702
|
+
* Dry-run mode: validate each spec and return predicted IDs without
|
|
703
|
+
* writing to the database. Created count is always 0 in dry-run.
|
|
704
|
+
*/
|
|
705
|
+
dryRun?: boolean;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Result of `tasks.add-batch`.
|
|
710
|
+
*
|
|
711
|
+
* @task T9814
|
|
712
|
+
*/
|
|
713
|
+
export interface TasksAddBatchResult {
|
|
714
|
+
/** Number of tasks actually created (0 on rollback or dry-run). */
|
|
715
|
+
created: number;
|
|
716
|
+
/** Per-task results in input order. */
|
|
717
|
+
tasks: TasksAddResult[];
|
|
718
|
+
/** Whether this was a dry run. */
|
|
719
|
+
dryRun?: boolean;
|
|
720
|
+
}
|
|
721
|
+
|
|
656
722
|
// tasks.add (dispatch-level params — extends TasksCreateParams)
|
|
657
723
|
export interface TasksAddParams {
|
|
658
724
|
title: string;
|
|
@@ -1043,6 +1109,7 @@ export type TasksOps = {
|
|
|
1043
1109
|
readonly 'sync.links': readonly [TasksSyncLinksParams, TasksSyncLinksResult];
|
|
1044
1110
|
// Mutate ops
|
|
1045
1111
|
readonly add: readonly [TasksAddParams, TasksAddResult];
|
|
1112
|
+
readonly 'add-batch': readonly [TasksAddBatchParams, TasksAddBatchResult];
|
|
1046
1113
|
readonly update: readonly [TasksUpdateQueryParams, TasksUpdateQueryResult];
|
|
1047
1114
|
readonly complete: readonly [TasksCompleteQueryParams, TasksCompleteQueryResult];
|
|
1048
1115
|
readonly cancel: readonly [TasksCancelParams, TasksCancelResult];
|