@unbrained/pm-cli 2026.8.27 → 2026.8.29
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +49 -1
- package/dist/cli/error-guidance.js +61 -7
- package/dist/cli/register-annotations.js +58 -41
- package/dist/cli-bundle/bundle-manifest.json +142 -142
- package/dist/cli-bundle/chunks/{chunk-TNX6HC54.js → chunk-2MKLQL2E.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SKXLJIEK.js → chunk-2UETTHY6.js} +49 -49
- package/dist/cli-bundle/chunks/{chunk-SHMDY36D.js → chunk-3TEF3HM5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SH6P7FXI.js → chunk-7SKMLSMX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +34 -0
- package/dist/cli-bundle/chunks/{chunk-CVBBGWW5.js → chunk-CMIEDWAY.js} +54 -50
- package/dist/cli-bundle/chunks/{chunk-3OO3W6FW.js → chunk-GNWPTEBW.js} +64 -61
- package/dist/cli-bundle/chunks/chunk-MTTKAUBX.js +2 -0
- package/dist/cli-bundle/chunks/chunk-N6OR6FAR.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-R4ETAOJC.js → chunk-TGNAA66W.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-52EKTW6V.js → chunk-WS2GJQVG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-EUWM6VII.js → register-list-query-OMKJ5ONN.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-FD4HSAVU.js → register-mutation-QBSNCOY3.js} +4 -4
- package/dist/cli-bundle/chunks/{register-operations-HRMNFEC3.js → register-operations-UC77FQZC.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-33GNICLX.js → register-setup-GLQ5SYV3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-HC7ODMH3.js → chunk-3AVAWVZA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3UMBF26I.js +158 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YVVZ3LQ6.js → chunk-73EDXGYE.js} +16 -15
- package/dist/cli-bundle/focused-chunks/{chunk-4BR5UU52.js → chunk-AXZ5AJAF.js} +45 -45
- package/dist/cli-bundle/focused-chunks/{chunk-MXTYGECH.js → chunk-G6PATS5E.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-SUBSWYW3.js → chunk-JZYPPMXF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-LYFWQMVC.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-RKOKG43G.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-TDK3OCX3.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EKX37ZHA.js → chunk-THEPQMLX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FC2AXLB5.js → chunk-XXOWRJZ5.js} +2 -2
- package/dist/cli-bundle/main.js +14 -14
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +31 -32
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +34 -32
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/diagnostics/remediation.js +16 -6
- package/dist/core/history/drift-scan.d.ts +2 -0
- package/dist/core/history/drift-scan.js +72 -36
- package/dist/core/history/history.d.ts +3 -3
- package/dist/core/history/history.js +5 -5
- package/dist/core/history/replay.d.ts +1 -1
- package/dist/core/history/replay.js +50 -19
- package/dist/core/item/actionability.d.ts +7 -1
- package/dist/core/item/actionability.js +44 -11
- package/dist/core/item/dependency-reference.d.ts +10 -0
- package/dist/core/item/dependency-reference.js +21 -0
- package/dist/core/item/parse.d.ts +4 -0
- package/dist/core/item/parse.js +38 -16
- package/dist/core/shared/author.js +69 -17
- package/dist/mcp/tool-definitions.js +5 -5
- package/dist/sdk/agent/command-recovery.js +3 -3
- package/dist/sdk/agent/task-transcript-contracts.d.ts +52 -0
- package/dist/sdk/agent/task-transcript-contracts.js +198 -0
- package/dist/sdk/annotations.d.ts +5 -2
- package/dist/sdk/annotations.js +66 -36
- package/dist/sdk/cli-bootstrap.d.ts +2 -8
- package/dist/sdk/cli-bootstrap.js +7 -67
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.d.ts +23 -0
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +80 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +5 -2
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +5 -5
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +16 -3
- package/dist/sdk/comments.d.ts +4 -0
- package/dist/sdk/comments.js +2 -2
- package/dist/sdk/completion.js +9 -5
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/dependency-provenance.d.ts +51 -2
- package/dist/sdk/dependency-provenance.js +91 -7
- package/dist/sdk/extension/install-sources.d.ts +8 -1
- package/dist/sdk/extension/install-sources.js +132 -39
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +86 -38
- package/dist/sdk/governance/health.js +86 -22
- package/dist/sdk/governance/validate-history-drift.js +5 -2
- package/dist/sdk/graph/assembly.js +51 -22
- package/dist/sdk/history-repair.d.ts +1 -1
- package/dist/sdk/history-repair.js +20 -10
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.js +3 -2
- package/dist/sdk/learnings.d.ts +4 -0
- package/dist/sdk/learnings.js +7 -4
- package/dist/sdk/lifecycle/close.js +4 -3
- package/dist/sdk/lifecycle/create.js +43 -19
- package/dist/sdk/linked-artifacts.js +21 -31
- package/dist/sdk/merge/reconcile.js +3 -16
- package/dist/sdk/notes.d.ts +4 -0
- package/dist/sdk/notes.js +2 -2
- package/dist/sdk/query/next.d.ts +6 -0
- package/dist/sdk/query/next.js +7 -2
- package/dist/sdk/runtime-input.js +5 -2
- package/dist/sdk/runtime.d.ts +6 -6
- package/dist/sdk/runtime.js +8 -8
- package/dist/sdk/test/entry.d.ts +1 -1
- package/dist/sdk/test/entry.js +5 -9
- package/dist/sdk/test/execution.d.ts +3 -0
- package/dist/sdk/test/execution.js +54 -13
- package/docs/COMMANDS.md +4 -3
- package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +67 -0
- package/docs/MERGE_SAFETY.md +23 -10
- package/docs/OUTPUT_TOKEN_ACCOUNTING.md +20 -7
- package/docs/README.md +1 -0
- package/docs/RELEASING.md +9 -1
- package/docs/SDK.md +12 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +12 -1
- package/docs/SDK_RUNTIME_BOUNDARIES.md +10 -0
- package/docs/TESTING.md +6 -2
- package/docs/agent-task-token-baseline.json +97 -11
- package/docs/agent-task-transcripts.json +211 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -3
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -4
- package/docs/performance/cli-transport-overhead.md +10 -2
- package/marketplace.json +2 -2
- package/package.json +8 -8
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +297 -36
- package/dist/cli-bundle/chunks/chunk-MFNTKMTI.js +0 -13
- package/dist/cli-bundle/chunks/chunk-OS27HHBN.js +0 -35
- package/dist/cli-bundle/chunks/chunk-QTO7USTH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2AGZ5BRT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AQ5IYEZZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-XDPYBQCF.js +0 -156
- package/dist/cli-bundle/focused-chunks/chunk-Y5A7SJJ7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-YHWHX6YY.js +0 -2
package/dist/core/item/parse.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines item parsing, formatting, and lifecycle helpers for Parse.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="80965b57-856c-5fef-a372-0c9f3766ada5")}catch(e){}}();
|
|
8
8
|
import { PmCliError } from "../shared/errors.js";
|
|
9
9
|
import { EXIT_CODE } from "../shared/constants.js";
|
|
10
10
|
const STDIN_TOKEN = "-";
|
|
@@ -30,6 +30,16 @@ const CONTINUABLE_VALUE_KEYS = new Set([
|
|
|
30
30
|
"value",
|
|
31
31
|
"why_now",
|
|
32
32
|
]);
|
|
33
|
+
/** Classify plaintext as structured key/value input using an explicit accepted-key vocabulary. */
|
|
34
|
+
export function looksLikeStructuredKeyValueEntry(raw, keys) {
|
|
35
|
+
if (raw.startsWith("```") || raw.includes("\n")) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const keyPattern = keys
|
|
39
|
+
.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
|
|
40
|
+
.join("|");
|
|
41
|
+
return new RegExp(`^(?:[-*+]\\s+)?(?:${keyPattern})\\s*[:=]`, "i").test(raw);
|
|
42
|
+
}
|
|
33
43
|
/** Implements parse tags for the public runtime surface of this module. */
|
|
34
44
|
export function parseTags(raw) {
|
|
35
45
|
const trimmed = raw.trim();
|
|
@@ -188,16 +198,16 @@ function splitCsvSegments(raw) {
|
|
|
188
198
|
const segments = [];
|
|
189
199
|
let current = "";
|
|
190
200
|
let inQuotes = false;
|
|
191
|
-
let
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
current +=
|
|
195
|
-
|
|
201
|
+
for (let index = 0; index < raw.length; index += 1) {
|
|
202
|
+
const char = raw[index];
|
|
203
|
+
if (char === "\\" && raw[index + 1] === ",") {
|
|
204
|
+
current += ",";
|
|
205
|
+
index += 1;
|
|
196
206
|
continue;
|
|
197
207
|
}
|
|
198
|
-
if (char === "\\") {
|
|
199
|
-
current += char
|
|
200
|
-
|
|
208
|
+
if (char === "\\" && raw[index + 1] !== undefined) {
|
|
209
|
+
current += `${char}${raw[index + 1]}`;
|
|
210
|
+
index += 1;
|
|
201
211
|
continue;
|
|
202
212
|
}
|
|
203
213
|
if (char === '"') {
|
|
@@ -206,14 +216,14 @@ function splitCsvSegments(raw) {
|
|
|
206
216
|
continue;
|
|
207
217
|
}
|
|
208
218
|
if (char === "," && !inQuotes) {
|
|
209
|
-
segments.push(current
|
|
219
|
+
segments.push(current);
|
|
210
220
|
current = "";
|
|
211
221
|
continue;
|
|
212
222
|
}
|
|
213
223
|
current += char;
|
|
214
224
|
}
|
|
215
225
|
if (current.trim()) {
|
|
216
|
-
segments.push(current
|
|
226
|
+
segments.push(current);
|
|
217
227
|
}
|
|
218
228
|
return segments;
|
|
219
229
|
}
|
|
@@ -235,8 +245,8 @@ function unquoteValue(value) {
|
|
|
235
245
|
function findKeyValueDelimiter(segment) {
|
|
236
246
|
const equalsIndex = segment.indexOf("=");
|
|
237
247
|
const colonIndex = segment.indexOf(":");
|
|
238
|
-
const hasEquals = equalsIndex
|
|
239
|
-
const hasColon = colonIndex
|
|
248
|
+
const hasEquals = equalsIndex >= 0;
|
|
249
|
+
const hasColon = colonIndex >= 0;
|
|
240
250
|
if (hasEquals && hasColon) {
|
|
241
251
|
return Math.min(equalsIndex, colonIndex);
|
|
242
252
|
}
|
|
@@ -324,15 +334,18 @@ export function parseCsvKv(raw, optionName) {
|
|
|
324
334
|
const segments = splitCsvSegments(trimmed);
|
|
325
335
|
for (const segment of segments) {
|
|
326
336
|
const delimiterIndex = findKeyValueDelimiter(segment);
|
|
327
|
-
if (delimiterIndex
|
|
337
|
+
if (delimiterIndex >= 0) {
|
|
328
338
|
const key = segment.slice(0, delimiterIndex).trim();
|
|
339
|
+
if (!key) {
|
|
340
|
+
throw new PmCliError(buildInvalidKvMessage(raw, optionName), EXIT_CODE.USAGE);
|
|
341
|
+
}
|
|
329
342
|
const value = unquoteValue(segment.slice(delimiterIndex + 1).trim());
|
|
330
343
|
result[key] = value;
|
|
331
344
|
activeKey = key;
|
|
332
345
|
continue;
|
|
333
346
|
}
|
|
334
347
|
if (activeKey && CONTINUABLE_VALUE_KEYS.has(activeKey.toLowerCase())) {
|
|
335
|
-
result[activeKey] = `${result[activeKey]},${segment
|
|
348
|
+
result[activeKey] = `${result[activeKey]},${segment}`;
|
|
336
349
|
continue;
|
|
337
350
|
}
|
|
338
351
|
throw new PmCliError(buildInvalidKvMessage(raw, optionName), EXIT_CODE.USAGE);
|
|
@@ -358,6 +371,15 @@ export function looksLikeGenericKeyValueEntry(raw) {
|
|
|
358
371
|
}
|
|
359
372
|
return GENERIC_LEADING_KV_KEY_PATTERN.test(trimmed);
|
|
360
373
|
}
|
|
374
|
+
/** Refuse a comma-bearing bare value whose meaning depends on guessing whether the comma separates values or belongs to one value. */
|
|
375
|
+
export function assertNoAmbiguousBareCommaEntry(raw, optionName, noun, structured) {
|
|
376
|
+
if (structured || !raw.includes(","))
|
|
377
|
+
return;
|
|
378
|
+
throw new PmCliError(`${optionName} received an ambiguous comma-bearing bare ${noun}. Repeat ${optionName} for multiple values, or quote or escape literal commas in a structured key=<value> entry.`, EXIT_CODE.USAGE, {
|
|
379
|
+
code: "bare_comma_entry_ambiguous",
|
|
380
|
+
required: `Use one ${optionName} per bare ${noun}, or quote or escape literal commas in a structured key=<value> entry.`,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
361
383
|
/**
|
|
362
384
|
* Reject any key in a parsed CSV/markdown key/value map that is not part of the
|
|
363
385
|
* caller's allowed-key contract, mirroring the strict `test --add` behavior
|
|
@@ -579,4 +601,4 @@ export const _testOnly = {
|
|
|
579
601
|
parseMarkdownKeyValueLines,
|
|
580
602
|
};
|
|
581
603
|
//# sourceMappingURL=parse.js.map
|
|
582
|
-
//# debugId=
|
|
604
|
+
//# debugId=80965b57-856c-5fef-a372-0c9f3766ada5
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides shared primitives and utilities for Author.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cf550961-0040-5e04-9d8d-16e316027e43")}catch(e){}}();
|
|
8
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import fs from "node:fs";
|
|
@@ -312,20 +312,50 @@ const MAX_PROVENANCE_PROBE_BYTES = 1_048_576;
|
|
|
312
312
|
const MAX_CODEX_PROVENANCE_PROBE_BYTES = 4_194_304;
|
|
313
313
|
const codexProvenanceSnapshotCache = new Map();
|
|
314
314
|
const EMPTY_CODEX_PROVENANCE_SNAPSHOT = Object.freeze({});
|
|
315
|
-
|
|
315
|
+
const claudeProvenanceSnapshotCache = new Map();
|
|
316
|
+
const EMPTY_CLAUDE_PROVENANCE_SNAPSHOT = Object.freeze({});
|
|
317
|
+
function asProvenanceRecord(value) {
|
|
318
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
319
|
+
? value
|
|
320
|
+
: undefined;
|
|
321
|
+
}
|
|
322
|
+
function parseClaudeProvenanceLine(line) {
|
|
316
323
|
let parsed;
|
|
317
324
|
try {
|
|
318
325
|
parsed = JSON.parse(line);
|
|
319
326
|
}
|
|
320
327
|
catch {
|
|
321
|
-
return
|
|
328
|
+
return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT;
|
|
322
329
|
}
|
|
323
|
-
const record = parsed;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
330
|
+
const record = asProvenanceRecord(parsed);
|
|
331
|
+
if (!record)
|
|
332
|
+
return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT;
|
|
333
|
+
const queue = [
|
|
334
|
+
{ value: record, depth: 0 },
|
|
335
|
+
];
|
|
336
|
+
let visited = 0;
|
|
337
|
+
let model;
|
|
338
|
+
let version;
|
|
339
|
+
while (queue.length > 0 && visited < 64) {
|
|
340
|
+
const current = queue.shift();
|
|
341
|
+
visited += 1;
|
|
342
|
+
model ??= nonBlank(current.value.model)?.slice(0, 256);
|
|
343
|
+
version ??= nonBlank(current.value.version)?.slice(0, 256);
|
|
344
|
+
if (model && version)
|
|
345
|
+
break;
|
|
346
|
+
if (current.depth >= 4)
|
|
347
|
+
continue;
|
|
348
|
+
for (const value of Object.values(current.value)) {
|
|
349
|
+
const nested = asProvenanceRecord(value);
|
|
350
|
+
if (nested) {
|
|
351
|
+
queue.push({
|
|
352
|
+
value: nested,
|
|
353
|
+
depth: current.depth + 1,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return Object.freeze({ model, version });
|
|
329
359
|
}
|
|
330
360
|
function readClaudeSessionProvenance(dimension, signals, env) {
|
|
331
361
|
const session = nonBlank(env.CLAUDE_CODE_SESSION_ID);
|
|
@@ -337,18 +367,40 @@ function readClaudeSessionProvenance(dimension, signals, env) {
|
|
|
337
367
|
try {
|
|
338
368
|
const file = fs.openSync(sessionPath, "r");
|
|
339
369
|
try {
|
|
340
|
-
const
|
|
341
|
-
const
|
|
370
|
+
const stats = fs.fstatSync(file);
|
|
371
|
+
const cacheKey = `${sessionPath}\u0000${stats.size}\u0000${stats.mtimeMs}`;
|
|
372
|
+
const cached = claudeProvenanceSnapshotCache.get(cacheKey);
|
|
373
|
+
if (cached)
|
|
374
|
+
return cached[dimension];
|
|
375
|
+
const probeLength = Math.min(stats.size, MAX_PROVENANCE_PROBE_BYTES);
|
|
376
|
+
const headLength = Math.min(probeLength, Math.ceil(probeLength / 2));
|
|
377
|
+
const tailLength = Math.min(probeLength - headLength, stats.size - headLength);
|
|
378
|
+
const head = Buffer.alloc(headLength);
|
|
379
|
+
fs.readSync(file, head, 0, headLength, 0);
|
|
342
380
|
const tail = Buffer.alloc(tailLength);
|
|
343
|
-
|
|
344
|
-
|
|
381
|
+
if (tailLength > 0) {
|
|
382
|
+
fs.readSync(file, tail, 0, tailLength, stats.size - tailLength);
|
|
383
|
+
}
|
|
384
|
+
const snapshot = {};
|
|
385
|
+
const lines = stats.size <= probeLength
|
|
386
|
+
? Buffer.concat([head, tail]).toString("utf8").split("\n")
|
|
387
|
+
: [
|
|
388
|
+
...head.toString("utf8").split("\n").slice(0, 4_096),
|
|
389
|
+
...tail.toString("utf8").split("\n").slice(-4_096),
|
|
390
|
+
];
|
|
345
391
|
for (const line of lines) {
|
|
346
392
|
if (line.length === 0 || line.length > 262_144)
|
|
347
393
|
continue;
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
394
|
+
const parsed = parseClaudeProvenanceLine(line);
|
|
395
|
+
snapshot.model ??= parsed.model;
|
|
396
|
+
snapshot.version ??= parsed.version;
|
|
397
|
+
if (snapshot.model && snapshot.version)
|
|
398
|
+
break;
|
|
351
399
|
}
|
|
400
|
+
const frozen = Object.freeze(snapshot);
|
|
401
|
+
claudeProvenanceSnapshotCache.clear();
|
|
402
|
+
claudeProvenanceSnapshotCache.set(cacheKey, frozen);
|
|
403
|
+
return frozen[dimension];
|
|
352
404
|
}
|
|
353
405
|
finally {
|
|
354
406
|
fs.closeSync(file);
|
|
@@ -1030,4 +1082,4 @@ export function resolveAuthor(candidate, fallback) {
|
|
|
1030
1082
|
return identity.author;
|
|
1031
1083
|
}
|
|
1032
1084
|
//# sourceMappingURL=author.js.map
|
|
1033
|
-
//# debugId=
|
|
1085
|
+
//# debugId=cf550961-0040-5e04-9d8d-16e316027e43
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines the Tool Definitions module for pm CLI source.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="41396cb5-7faf-5642-8746-8d94edb01d86")}catch(e){}}();
|
|
8
8
|
import { GRAPH_SUBCOMMAND_VALUES, PM_DISCOVERABLE_TOOL_ACTIONS, } from "../sdk/cli-contracts/enum-contracts.js";
|
|
9
9
|
import { buildPmActionToolInputSchema } from "../sdk/cli-contracts/tool-schema.js";
|
|
10
10
|
import { RUNTIME_STATUS_ROLE_VALUES } from "../types.js";
|
|
@@ -413,7 +413,7 @@ const RAW_TOOLS = [
|
|
|
413
413
|
},
|
|
414
414
|
{
|
|
415
415
|
name: "pm_comments",
|
|
416
|
-
description: "List, add, edit, or delete comments on a pm item. Use options.add to append, options.edit=<1-based index> with replacement text to fix a comment, or options.delete=<1-based index> to remove one. " +
|
|
416
|
+
description: "List, add, edit, or delete comments on a pm item. Use options.add to append, options.edit=<1-based index> with replacement text to fix a comment, or options.delete=<1-based index> to remove one. options.ifAbsent applies only to options.add for retry-safe author-and-text deduplication and cannot combine with options.edit or options.delete. " +
|
|
417
417
|
"List calls default to the most recent 20 comments with total_count/has_more metadata for token efficiency. " +
|
|
418
418
|
"Pass options.limit=N to choose a page size, options.limit=0 for summary-only metadata, or options.full=true for full history.",
|
|
419
419
|
inputSchema: objectSchema({ id: idSchema, options: { type: "object" } }, [
|
|
@@ -436,14 +436,14 @@ const RAW_TOOLS = [
|
|
|
436
436
|
},
|
|
437
437
|
{
|
|
438
438
|
name: "pm_notes",
|
|
439
|
-
description: "List or
|
|
439
|
+
description: "List, add, edit, or delete structured notes on a pm item. options.ifAbsent applies only to options.add for retry-safe author-and-text deduplication and cannot combine with options.edit or options.delete. Omit mutation options to list existing notes.",
|
|
440
440
|
inputSchema: objectSchema({ id: idSchema, options: { type: "object" } }, [
|
|
441
441
|
"id",
|
|
442
442
|
]),
|
|
443
443
|
},
|
|
444
444
|
{
|
|
445
445
|
name: "pm_learnings",
|
|
446
|
-
description: "List or
|
|
446
|
+
description: "List, add, edit, or delete learnings on a pm item. options.ifAbsent applies only to options.add for retry-safe author-and-text deduplication and cannot combine with options.edit or options.delete. Omit mutation options to list existing learnings.",
|
|
447
447
|
inputSchema: objectSchema({ id: idSchema, options: { type: "object" } }, [
|
|
448
448
|
"id",
|
|
449
449
|
]),
|
|
@@ -748,4 +748,4 @@ export function buildMcpToolContracts() {
|
|
|
748
748
|
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
749
749
|
}
|
|
750
750
|
//# sourceMappingURL=tool-definitions.js.map
|
|
751
|
-
//# debugId=
|
|
751
|
+
//# debugId=41396cb5-7faf-5642-8746-8d94edb01d86
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* supplied arguments are preserved byte-for-token.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
9
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6084a18e-ccda-57f9-a7d8-45572799c021")}catch(e){}}();
|
|
10
10
|
import { renderPmCommand } from "../command-line.js";
|
|
11
11
|
import { resolveSubcommandFlagContractsForCommand } from "../cli-contracts.js";
|
|
12
|
-
import { parseBootstrapCommandName } from "../cli-bootstrap.js";
|
|
12
|
+
import { parseBootstrapCommandName } from "../cli-contracts/bootstrap-command-scanner.js";
|
|
13
13
|
function normalizeMissingFlag(label) {
|
|
14
14
|
const match = label.trim().match(/--[a-z0-9][a-z0-9_-]*/i);
|
|
15
15
|
return match?.[0]?.replaceAll("_", "-").toLowerCase();
|
|
@@ -57,4 +57,4 @@ export function renderMissingOptionRetry(invocationArgv, commandName, missingLab
|
|
|
57
57
|
: renderPmCommand(retry);
|
|
58
58
|
}
|
|
59
59
|
//# sourceMappingURL=command-recovery.js.map
|
|
60
|
-
//# debugId=
|
|
60
|
+
//# debugId=6084a18e-ccda-57f9-a7d8-45572799c021
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type PmOutputEnvelopeKind } from "../output-contracts.js";
|
|
2
|
+
/** Stable schema version for replayable agent-task transcript corpora. */
|
|
3
|
+
export declare const PM_AGENT_TASK_TRANSCRIPT_VERSION: 2;
|
|
4
|
+
/** Supported strategies for measuring one transcript step's output cost. */
|
|
5
|
+
export declare const PM_AGENT_TASK_ACCOUNTING_MODES: readonly ["self_reported", "independent_transport"];
|
|
6
|
+
/** Token-accounting strategy a replayed transcript step must preserve. */
|
|
7
|
+
export type PmAgentTaskAccountingMode = (typeof PM_AGENT_TASK_ACCOUNTING_MODES)[number];
|
|
8
|
+
/** Scalar value that a replayed transcript must observe at one output path. */
|
|
9
|
+
export type PmAgentTaskExpectedFieldValue = string | number | boolean | null;
|
|
10
|
+
/** Output family expected from one replayed agent-task step. */
|
|
11
|
+
export type PmAgentTaskStepOutputKind = PmOutputEnvelopeKind | "refusal";
|
|
12
|
+
/** Declares one real CLI invocation within a replayable agent task. */
|
|
13
|
+
export interface PmAgentTaskTranscriptStep {
|
|
14
|
+
/** Stable step identifier unique within its task. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Shell-free CLI arguments, excluding the pm executable, preserved exactly. */
|
|
17
|
+
args: readonly string[];
|
|
18
|
+
/** Process status required for the step to satisfy the transcript. */
|
|
19
|
+
expected_exit_code: number;
|
|
20
|
+
/** Semantic output family required from the transport. */
|
|
21
|
+
expected_output_kind: PmAgentTaskStepOutputKind;
|
|
22
|
+
/** Accounting strategy required from the measured transport. */
|
|
23
|
+
expected_accounting_mode: PmAgentTaskAccountingMode;
|
|
24
|
+
/** Dot-separated own-property paths proving required context was consumed. */
|
|
25
|
+
required_fields: readonly string[];
|
|
26
|
+
/** Exact terminal scalar values required at selected output paths. */
|
|
27
|
+
expected_field_values?: Readonly<Record<string, PmAgentTaskExpectedFieldValue>>;
|
|
28
|
+
/** Stable diagnostic code required from a refusal step. */
|
|
29
|
+
expected_error_code?: string;
|
|
30
|
+
/** Exact command or flag required in a refusal identity. */
|
|
31
|
+
expected_refusal_surface?: string;
|
|
32
|
+
/** Earlier refusal step whose recovery this successful step executes. */
|
|
33
|
+
recovery_for?: string;
|
|
34
|
+
}
|
|
35
|
+
/** Versioned multi-step agent workflow suitable for deterministic replay. */
|
|
36
|
+
export interface PmAgentTaskTranscript {
|
|
37
|
+
/** Stable task identifier used by baselines and reports. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Human-readable task outcome represented by the transcript. */
|
|
40
|
+
description: string;
|
|
41
|
+
/** Ordered invocations whose shared workspace state completes the task. */
|
|
42
|
+
steps: readonly PmAgentTaskTranscriptStep[];
|
|
43
|
+
}
|
|
44
|
+
/** Published collection of replayable agent workflows. */
|
|
45
|
+
export interface PmAgentTaskTranscriptCorpus {
|
|
46
|
+
/** Schema version governing every transcript in the corpus. */
|
|
47
|
+
version: typeof PM_AGENT_TASK_TRANSCRIPT_VERSION;
|
|
48
|
+
/** Complete ordered task set evaluated by the release gate. */
|
|
49
|
+
tasks: readonly PmAgentTaskTranscript[];
|
|
50
|
+
}
|
|
51
|
+
/** Parse and fail closed on malformed or internally inconsistent transcripts. */
|
|
52
|
+
export declare function parsePmAgentTaskTranscriptCorpus(value: unknown): PmAgentTaskTranscriptCorpus;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/agent-task-transcript-contracts
|
|
3
|
+
*
|
|
4
|
+
* Defines and validates replayable agent-task transcripts without adding the
|
|
5
|
+
* SDK-only parser to ordinary CLI command bundles.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="006109f8-cb09-5a91-8929-7ac7521753b6")}catch(e){}}();
|
|
9
|
+
import { isPmSuccessfulExitCode, resolvePmCommandExitContract, } from "../cli-contracts/command-exit-contracts.js";
|
|
10
|
+
import { parseBootstrapCommandName } from "../cli-contracts/bootstrap-command-scanner.js";
|
|
11
|
+
import { PM_OUTPUT_ENVELOPE_KINDS, resolvePmCommandOutputEnvelope, } from "../output-contracts.js";
|
|
12
|
+
/** Stable schema version for replayable agent-task transcript corpora. */
|
|
13
|
+
export const PM_AGENT_TASK_TRANSCRIPT_VERSION = 2;
|
|
14
|
+
/** Supported strategies for measuring one transcript step's output cost. */
|
|
15
|
+
export const PM_AGENT_TASK_ACCOUNTING_MODES = [
|
|
16
|
+
"self_reported",
|
|
17
|
+
"independent_transport",
|
|
18
|
+
];
|
|
19
|
+
function isRecord(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
function readTranscriptString(value, field) {
|
|
23
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
24
|
+
throw new TypeError(`${field} must be a non-empty string`);
|
|
25
|
+
}
|
|
26
|
+
return value.trim();
|
|
27
|
+
}
|
|
28
|
+
function readTranscriptStringArray(value, field, preserveWhitespace = false) {
|
|
29
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
30
|
+
throw new TypeError(`${field} must be a non-empty string array`);
|
|
31
|
+
}
|
|
32
|
+
return value.map((entry, index) => {
|
|
33
|
+
const normalized = readTranscriptString(entry, `${field}[${String(index)}]`);
|
|
34
|
+
return preserveWhitespace ? entry : normalized;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function readOptionalTranscriptString(value, field) {
|
|
38
|
+
return value === undefined ? undefined : readTranscriptString(value, field);
|
|
39
|
+
}
|
|
40
|
+
function readExpectedFieldValues(value, field) {
|
|
41
|
+
if (value === undefined)
|
|
42
|
+
return undefined;
|
|
43
|
+
if (!isRecord(value) || Object.keys(value).length === 0) {
|
|
44
|
+
throw new TypeError(`${field} must be a non-empty object`);
|
|
45
|
+
}
|
|
46
|
+
const entries = Object.entries(value).map(([path, expectedValue]) => {
|
|
47
|
+
if (path.length === 0 ||
|
|
48
|
+
path.split(".").some((segment) => segment.length === 0)) {
|
|
49
|
+
throw new TypeError(`${field} must use dot-separated own-property paths`);
|
|
50
|
+
}
|
|
51
|
+
if (expectedValue !== null &&
|
|
52
|
+
typeof expectedValue !== "string" &&
|
|
53
|
+
typeof expectedValue !== "boolean" &&
|
|
54
|
+
(typeof expectedValue !== "number" || !Number.isFinite(expectedValue))) {
|
|
55
|
+
throw new TypeError(`${field} values must be JSON primitives`);
|
|
56
|
+
}
|
|
57
|
+
return [path, expectedValue];
|
|
58
|
+
});
|
|
59
|
+
return Object.fromEntries(entries);
|
|
60
|
+
}
|
|
61
|
+
function assertTranscriptStepOutputContract(field, args, exitCode, outputKind, errorCode, refusalSurface) {
|
|
62
|
+
if (outputKind === "refusal") {
|
|
63
|
+
if (isPmSuccessfulExitCode(exitCode) ||
|
|
64
|
+
errorCode === undefined ||
|
|
65
|
+
refusalSurface === undefined) {
|
|
66
|
+
throw new TypeError(`${field} refusal steps require a non-success exit, error code, and refusal surface`);
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (errorCode !== undefined || refusalSurface !== undefined) {
|
|
71
|
+
throw new TypeError(`${field} only refusal steps may declare expected_error_code or expected_refusal_surface`);
|
|
72
|
+
}
|
|
73
|
+
const command = parseBootstrapCommandName(args);
|
|
74
|
+
if (command === undefined) {
|
|
75
|
+
throw new TypeError(`${field}.args must identify a command after global flags`);
|
|
76
|
+
}
|
|
77
|
+
const exitContract = resolvePmCommandExitContract(command);
|
|
78
|
+
if (!isPmSuccessfulExitCode(exitCode) ||
|
|
79
|
+
(exitCode !== 0 &&
|
|
80
|
+
!exitContract?.exit_codes.some((declaredExitCode) => declaredExitCode === exitCode))) {
|
|
81
|
+
throw new TypeError(`${field} successful output must use exit code 0 or a command-declared successful effect exit`);
|
|
82
|
+
}
|
|
83
|
+
const declaredKind = resolvePmCommandOutputEnvelope(command).kind;
|
|
84
|
+
if (outputKind !== declaredKind) {
|
|
85
|
+
throw new TypeError(`${field} expected ${outputKind}, but ${command} declares ${declaredKind}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function parseAgentTaskTranscriptStep(value, taskId, index) {
|
|
89
|
+
if (!isRecord(value)) {
|
|
90
|
+
throw new TypeError(`tasks.${taskId}.steps[${String(index)}] must be an object`);
|
|
91
|
+
}
|
|
92
|
+
const field = `tasks.${taskId}.steps[${String(index)}]`;
|
|
93
|
+
const id = readTranscriptString(value.id, `${field}.id`);
|
|
94
|
+
const args = readTranscriptStringArray(value.args, `${field}.args`, true);
|
|
95
|
+
const expectedExitCode = value.expected_exit_code;
|
|
96
|
+
if (typeof expectedExitCode !== "number" ||
|
|
97
|
+
!Number.isSafeInteger(expectedExitCode)) {
|
|
98
|
+
throw new TypeError(`${field}.expected_exit_code must be a safe integer`);
|
|
99
|
+
}
|
|
100
|
+
const rawOutputKind = value.expected_output_kind;
|
|
101
|
+
if (rawOutputKind !== "refusal" &&
|
|
102
|
+
!PM_OUTPUT_ENVELOPE_KINDS.includes(rawOutputKind)) {
|
|
103
|
+
throw new TypeError(`${field}.expected_output_kind is unsupported`);
|
|
104
|
+
}
|
|
105
|
+
const expectedOutputKind = rawOutputKind;
|
|
106
|
+
const rawAccountingMode = value.expected_accounting_mode;
|
|
107
|
+
if (!PM_AGENT_TASK_ACCOUNTING_MODES.includes(rawAccountingMode)) {
|
|
108
|
+
throw new TypeError(`${field}.expected_accounting_mode is unsupported`);
|
|
109
|
+
}
|
|
110
|
+
const expectedAccountingMode = rawAccountingMode;
|
|
111
|
+
if (expectedAccountingMode === "independent_transport" &&
|
|
112
|
+
expectedOutputKind !== "refusal") {
|
|
113
|
+
throw new TypeError(`${field} independent_transport accounting is supported only for refusal steps`);
|
|
114
|
+
}
|
|
115
|
+
const requiredFields = readTranscriptStringArray(value.required_fields, `${field}.required_fields`);
|
|
116
|
+
if (requiredFields.some((requiredField) => requiredField.split(".").some((segment) => segment.length === 0))) {
|
|
117
|
+
throw new TypeError(`${field}.required_fields must contain dot-separated own-property paths`);
|
|
118
|
+
}
|
|
119
|
+
const expectedFieldValues = readExpectedFieldValues(value.expected_field_values, `${field}.expected_field_values`);
|
|
120
|
+
const expectedErrorCode = readOptionalTranscriptString(value.expected_error_code, `${field}.expected_error_code`);
|
|
121
|
+
const expectedRefusalSurface = readOptionalTranscriptString(value.expected_refusal_surface, `${field}.expected_refusal_surface`);
|
|
122
|
+
const recoveryFor = readOptionalTranscriptString(value.recovery_for, `${field}.recovery_for`);
|
|
123
|
+
assertTranscriptStepOutputContract(field, args, expectedExitCode, expectedOutputKind, expectedErrorCode, expectedRefusalSurface);
|
|
124
|
+
return {
|
|
125
|
+
id,
|
|
126
|
+
args,
|
|
127
|
+
expected_exit_code: expectedExitCode,
|
|
128
|
+
expected_output_kind: expectedOutputKind,
|
|
129
|
+
expected_accounting_mode: expectedAccountingMode,
|
|
130
|
+
required_fields: requiredFields,
|
|
131
|
+
...(expectedFieldValues
|
|
132
|
+
? { expected_field_values: expectedFieldValues }
|
|
133
|
+
: {}),
|
|
134
|
+
...(expectedErrorCode ? { expected_error_code: expectedErrorCode } : {}),
|
|
135
|
+
...(expectedRefusalSurface
|
|
136
|
+
? { expected_refusal_surface: expectedRefusalSurface }
|
|
137
|
+
: {}),
|
|
138
|
+
...(recoveryFor ? { recovery_for: recoveryFor } : {}),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function parseAgentTaskTranscript(value, index) {
|
|
142
|
+
if (!isRecord(value)) {
|
|
143
|
+
throw new TypeError(`tasks[${String(index)}] must be an object`);
|
|
144
|
+
}
|
|
145
|
+
const id = readTranscriptString(value.id, `tasks[${String(index)}].id`);
|
|
146
|
+
const description = readTranscriptString(value.description, `tasks.${id}.description`);
|
|
147
|
+
if (!Array.isArray(value.steps) || value.steps.length === 0) {
|
|
148
|
+
throw new TypeError(`tasks.${id}.steps must be a non-empty array`);
|
|
149
|
+
}
|
|
150
|
+
const steps = value.steps.map((step, stepIndex) => parseAgentTaskTranscriptStep(step, id, stepIndex));
|
|
151
|
+
const priorSteps = new Map();
|
|
152
|
+
for (const step of steps) {
|
|
153
|
+
if (priorSteps.has(step.id)) {
|
|
154
|
+
throw new TypeError(`tasks.${id} contains duplicate step id ${step.id}`);
|
|
155
|
+
}
|
|
156
|
+
if (step.recovery_for !== undefined) {
|
|
157
|
+
const refusal = priorSteps.get(step.recovery_for);
|
|
158
|
+
if (refusal?.expected_output_kind !== "refusal" ||
|
|
159
|
+
step.expected_output_kind === "refusal") {
|
|
160
|
+
throw new TypeError(`tasks.${id}.${step.id} recovery_for must reference an earlier refusal and declare successful output`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
priorSteps.set(step.id, step);
|
|
164
|
+
}
|
|
165
|
+
if (steps.at(-1)?.expected_output_kind === "refusal") {
|
|
166
|
+
throw new TypeError(`tasks.${id} completed task must terminate with successful output`);
|
|
167
|
+
}
|
|
168
|
+
for (const step of steps) {
|
|
169
|
+
if (step.expected_output_kind === "refusal" &&
|
|
170
|
+
!steps.some((candidate) => candidate.recovery_for === step.id)) {
|
|
171
|
+
throw new TypeError(`tasks.${id}.${step.id} refusal must have a later successful recovery_for step`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { id, description, steps };
|
|
175
|
+
}
|
|
176
|
+
/** Parse and fail closed on malformed or internally inconsistent transcripts. */
|
|
177
|
+
export function parsePmAgentTaskTranscriptCorpus(value) {
|
|
178
|
+
if (!isRecord(value)) {
|
|
179
|
+
throw new TypeError("agent-task transcript corpus must be an object");
|
|
180
|
+
}
|
|
181
|
+
if (value.version !== PM_AGENT_TASK_TRANSCRIPT_VERSION) {
|
|
182
|
+
throw new TypeError(`agent-task transcript corpus version must be ${String(PM_AGENT_TASK_TRANSCRIPT_VERSION)}`);
|
|
183
|
+
}
|
|
184
|
+
if (!Array.isArray(value.tasks) || value.tasks.length === 0) {
|
|
185
|
+
throw new TypeError("agent-task transcript corpus tasks must be non-empty");
|
|
186
|
+
}
|
|
187
|
+
const tasks = value.tasks.map((task, index) => parseAgentTaskTranscript(task, index));
|
|
188
|
+
const taskIds = new Set();
|
|
189
|
+
for (const task of tasks) {
|
|
190
|
+
if (taskIds.has(task.id)) {
|
|
191
|
+
throw new TypeError(`duplicate agent-task transcript id ${task.id}`);
|
|
192
|
+
}
|
|
193
|
+
taskIds.add(task.id);
|
|
194
|
+
}
|
|
195
|
+
return { version: PM_AGENT_TASK_TRANSCRIPT_VERSION, tasks };
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=task-transcript-contracts.js.map
|
|
198
|
+
//# debugId=006109f8-cb09-5a91-8929-7ac7521753b6
|
|
@@ -25,6 +25,8 @@ export interface AnnotationCommandOptions {
|
|
|
25
25
|
includeMeta?: boolean;
|
|
26
26
|
/** Return the complete collection after a mutation instead of the bounded mutation receipt. */
|
|
27
27
|
fullHistory?: boolean;
|
|
28
|
+
/** Append only when no entry has the same resolved author and text. */
|
|
29
|
+
ifAbsent?: boolean;
|
|
28
30
|
}
|
|
29
31
|
/** Identifies the single annotation mutation represented by a bounded response. */
|
|
30
32
|
export interface AnnotationMutationReceipt {
|
|
@@ -32,8 +34,8 @@ export interface AnnotationMutationReceipt {
|
|
|
32
34
|
action: "add" | "edit" | "delete";
|
|
33
35
|
/** Stable one-based collection position targeted by the mutation. */
|
|
34
36
|
entry_index: number;
|
|
35
|
-
/** Number of stored entries changed by the mutation. */
|
|
36
|
-
changed_count: 1;
|
|
37
|
+
/** Number of stored entries changed by the mutation attempt. */
|
|
38
|
+
changed_count: 0 | 1;
|
|
37
39
|
/** Whether the response includes the complete post-mutation collection. */
|
|
38
40
|
full_history_included: boolean;
|
|
39
41
|
}
|
|
@@ -133,6 +135,7 @@ export type AnnotationCommandResult<TKey extends string, TEntry extends Annotati
|
|
|
133
135
|
limit?: number;
|
|
134
136
|
mutation_receipt?: AnnotationMutationReceipt;
|
|
135
137
|
omission_receipt?: AnnotationOmissionReceipt;
|
|
138
|
+
changed?: boolean;
|
|
136
139
|
};
|
|
137
140
|
/** Implements limit annotation entries for the public runtime surface of this module. */
|
|
138
141
|
export declare function limitAnnotationEntries<TEntry>(values: TEntry[], limit: number | undefined): TEntry[];
|