pm-context 2026.10.26 → 2026.10.28
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/CHANGELOG.md +32 -16
- package/README.md +124 -0
- package/dist/file-focus.d.ts +7 -2
- package/dist/file-focus.d.ts.map +1 -1
- package/dist/file-focus.js +17 -16
- package/dist/file-focus.js.map +1 -1
- package/dist/index.d.ts +24 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +110 -56
- package/dist/index.js.map +1 -1
- package/dist/since.d.ts +4 -1
- package/dist/since.d.ts.map +1 -1
- package/dist/since.js +6 -4
- package/dist/since.js.map +1 -1
- package/dist/suggested-command.d.ts +17 -0
- package/dist/suggested-command.d.ts.map +1 -0
- package/dist/suggested-command.js +21 -0
- package/dist/suggested-command.js.map +1 -0
- package/dist/task-phase.d.ts +90 -0
- package/dist/task-phase.d.ts.map +1 -0
- package/dist/task-phase.js +190 -0
- package/dist/task-phase.js.map +1 -0
- package/manifest.json +1 -1
- package/package.json +13 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggested-command.d.ts","sourceRoot":"","sources":["../suggested-command.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAAG,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AACrE,6FAA6F;AAC7F,MAAM,WAAW,gBAAgB;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE;AAElF,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,kGAAkG;AAClG,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAI/E;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAG7E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Shell-independent command suggestions with one auditable POSIX display renderer. */
|
|
2
|
+
import { PmCliError } from "@unbrained/pm-cli/sdk";
|
|
3
|
+
/** Preserve a single argument exactly, including empty strings and embedded single quotes. */
|
|
4
|
+
export function quotePosixArgument(value) {
|
|
5
|
+
if (value.includes("\0") || Buffer.from(value, "utf8").toString("utf8") !== value)
|
|
6
|
+
throw new PmCliError("Command arguments must be well-formed Unicode without NUL bytes.", 2, { code: "INVALID_COMMAND_ARGUMENT", nextSteps: ["Remove NUL bytes or malformed Unicode so UTF-8 argv preserves every argument exactly."] });
|
|
7
|
+
return /^[A-Za-z0-9_./:=,+-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
8
|
+
}
|
|
9
|
+
/** Copy and validate a dense bounded argv before rendering; never parse or execute shell text. */
|
|
10
|
+
export function buildSuggestedCommand(argv) {
|
|
11
|
+
if (!Array.isArray(argv) || argv.length < 1 || argv.length > 4096 || Object.keys(argv).length !== argv.length || !Array.from({ length: argv.length }, (_, i) => Object.hasOwn(argv, i) && typeof argv[i] === "string").every(Boolean) || Buffer.byteLength(JSON.stringify(argv)) > 262144)
|
|
12
|
+
throw new PmCliError("Supply a dense argv of 1-4096 strings, at most 262144 JSON bytes.", 2, { code: "INVALID_COMMAND_ARGUMENT", nextSteps: ["Supply argument strings instead of shell text; narrow oversized commands."] });
|
|
13
|
+
const copied = [...argv];
|
|
14
|
+
return { argv: copied, command: copied.map(quotePosixArgument).join(" ") };
|
|
15
|
+
}
|
|
16
|
+
/** Generate both restoration fields from the same original argv. */
|
|
17
|
+
export function buildRestoreCommand(argv) {
|
|
18
|
+
const value = buildSuggestedCommand(argv);
|
|
19
|
+
return { restore_with: value.command, restore_argv: value.argv };
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=suggested-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggested-command.js","sourceRoot":"","sources":["../suggested-command.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAOnD,8FAA8F;AAC9F,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK;QAAE,MAAM,IAAI,UAAU,CAAC,kEAAkE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,CAAC,uFAAuF,CAAC,EAAE,CAAC,CAAC;IAC3T,OAAO,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAC9F,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,qBAAqB,CAAC,IAAuB;IAC3D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM;QAAE,MAAM,IAAI,UAAU,CAAC,mEAAmE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,CAAC,2EAA2E,CAAC,EAAE,CAAC,CAAC;IACxf,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACzB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CAAC,IAAuB;IACzD,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { SuggestedCommand, SuggestedRestore } from "./suggested-command.ts";
|
|
2
|
+
import { PmCliError } from "@unbrained/pm-cli/sdk";
|
|
3
|
+
import type { OutputOmissionReceipt, PmReadOutputSessionReceipt, PmReadOutputSessionReference, PmReadOutputSessionState } from "@unbrained/pm-cli/sdk";
|
|
4
|
+
/** Phase selection describes a projection, never authority or a lifecycle transition. */
|
|
5
|
+
export declare const TASK_PHASES: readonly ["investigation", "implementation", "review", "handoff"];
|
|
6
|
+
/** The four independently declared context requirements. */
|
|
7
|
+
export type TaskPhase = typeof TASK_PHASES[number];
|
|
8
|
+
/** One strict request schema shared by the SDK and CLI, including transport controls. */
|
|
9
|
+
export interface PhaseContextRequest {
|
|
10
|
+
phase: TaskPhase;
|
|
11
|
+
contracts: Record<TaskPhase, string[]>;
|
|
12
|
+
items: string[];
|
|
13
|
+
previous_phase?: TaskPhase;
|
|
14
|
+
include_fields?: string[];
|
|
15
|
+
byte_budget?: number;
|
|
16
|
+
format?: "json" | "toon";
|
|
17
|
+
session?: PmReadOutputSessionState;
|
|
18
|
+
}
|
|
19
|
+
/** Safe refusals never include backend paths, exception messages or source values. */
|
|
20
|
+
export declare class PhaseContextError extends PmCliError {
|
|
21
|
+
/** Stable machine-readable reason for refusing the entire packet. */
|
|
22
|
+
readonly code: "INVALID_REQUEST" | "INPUT_UNAVAILABLE" | "SOURCE_UNAVAILABLE" | "MISSING_FIELD" | "BUDGET_TOO_SMALL" | "INVALID_OUTPUT";
|
|
23
|
+
/** Concrete retry action, also exposed through the host's next_steps. */
|
|
24
|
+
readonly remedy: string;
|
|
25
|
+
constructor(code: PhaseContextError["code"], remedy: string);
|
|
26
|
+
}
|
|
27
|
+
/** A field is restorable only when the host declares a compatible selector. */
|
|
28
|
+
export type PhaseFieldRestoration = (SuggestedRestore & {
|
|
29
|
+
restore_unavailable?: never;
|
|
30
|
+
}) | {
|
|
31
|
+
restore_unavailable: {
|
|
32
|
+
code: "UNSUPPORTED_FIELD_PROJECTION";
|
|
33
|
+
reason: string;
|
|
34
|
+
};
|
|
35
|
+
restore_with?: never;
|
|
36
|
+
restore_argv?: never;
|
|
37
|
+
};
|
|
38
|
+
/** Coordinates survive SDK reference suppression so every mandatory value remains resolvable. */
|
|
39
|
+
export type PhaseFieldBinding = PhaseFieldRestoration & {
|
|
40
|
+
item: string;
|
|
41
|
+
field: string;
|
|
42
|
+
fact: string;
|
|
43
|
+
mandatory: boolean;
|
|
44
|
+
};
|
|
45
|
+
/** Exact authoritative SDK field value; JSON strings preserve nested native collections. */
|
|
46
|
+
export interface PhaseFieldFact {
|
|
47
|
+
id: string;
|
|
48
|
+
value_json: string;
|
|
49
|
+
}
|
|
50
|
+
/** Field-by-field difference between two contracts from the same request. */
|
|
51
|
+
export interface PhaseFieldChange {
|
|
52
|
+
field: string;
|
|
53
|
+
change: "added" | "removed" | "retained";
|
|
54
|
+
reason: string;
|
|
55
|
+
}
|
|
56
|
+
/** Complete bounded packet; refusal is the only degradation when mandatory facts cannot fit. */
|
|
57
|
+
export interface PhaseContextPacket {
|
|
58
|
+
ok: true;
|
|
59
|
+
protocol: "pm-context-phase/v1";
|
|
60
|
+
phase: TaskPhase;
|
|
61
|
+
previous_phase: TaskPhase | null;
|
|
62
|
+
mandatory_fields: string[];
|
|
63
|
+
changes: PhaseFieldChange[];
|
|
64
|
+
bindings: PhaseFieldBinding[];
|
|
65
|
+
facts: Array<PhaseFieldFact | PmReadOutputSessionReference>;
|
|
66
|
+
omission_receipt: Omit<OutputOmissionReceipt, "omitted_field_groups"> & {
|
|
67
|
+
omitted_field_groups: Array<{
|
|
68
|
+
name: string;
|
|
69
|
+
} & PhaseFieldRestoration>;
|
|
70
|
+
};
|
|
71
|
+
/** Exact complete encoded size including the trailing newline and this counter. */
|
|
72
|
+
bytes: number;
|
|
73
|
+
byte_budget: number;
|
|
74
|
+
format: "json" | "toon";
|
|
75
|
+
/** SDK session ids name field facts; bindings carry their native item restore commands. */
|
|
76
|
+
session_fact_scope: "item-field-value;restore-with-bindings";
|
|
77
|
+
/** SDK-owned charging conservatively includes its removed legacy restore template. */
|
|
78
|
+
read_session?: Omit<PmReadOutputSessionReceipt, "restore_reference_with">;
|
|
79
|
+
/** Concrete identity probe only; value restoration is exclusively described by bindings. */
|
|
80
|
+
session_restore?: SuggestedCommand;
|
|
81
|
+
}
|
|
82
|
+
/** Validate untrusted input once before reading sources; never normalize tracker content. */
|
|
83
|
+
export declare function parsePhaseContextRequest(value: unknown): PhaseContextRequest;
|
|
84
|
+
/** Read bounded regular UTF-8 JSON; the shared builder owns schema validation. */
|
|
85
|
+
export declare function readPhaseContextJson(path: string): unknown;
|
|
86
|
+
/** Serialize only valid finite JSON data, preserving exact source strings and arrays. */
|
|
87
|
+
export declare function encodePhaseContext(packet: PhaseContextPacket): string;
|
|
88
|
+
/** Build mandatory projections using SDK intent resolution, omission receipts and session reuse. */
|
|
89
|
+
export declare function buildPhaseContext(input: PhaseContextRequest, pmRoot: string): Promise<PhaseContextPacket>;
|
|
90
|
+
//# sourceMappingURL=task-phase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-phase.d.ts","sourceRoot":"","sources":["../task-phase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { buildRestoreCommand, buildSuggestedCommand } from "./suggested-command.js";
|
|
2
|
+
/** Mandatory field contracts over cache-free SDK reads and caller-carried SDK sessions. */
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { encode } from "@toon-format/toon";
|
|
5
|
+
import { PmCliError, applyReadOutputSessionReferences, attachReadOutputSessionReceipt, composeContextIntentContracts, createOutputOmissionReceipt, parseReadOutputSession, resolveContextIntentContract, resolveRuntimeFieldRegistry, } from "@unbrained/pm-cli/sdk";
|
|
6
|
+
import { listGetProjectionFields, listListProjectionFields } from "@unbrained/pm-cli/sdk/query";
|
|
7
|
+
import { createFreshnessReader, readFreshnessJson } from "./freshness.js";
|
|
8
|
+
/** Phase selection describes a projection, never authority or a lifecycle transition. */
|
|
9
|
+
export const TASK_PHASES = ["investigation", "implementation", "review", "handoff"];
|
|
10
|
+
/** Safe refusals never include backend paths, exception messages or source values. */
|
|
11
|
+
export class PhaseContextError extends PmCliError {
|
|
12
|
+
/** Concrete retry action, also exposed through the host's next_steps. */
|
|
13
|
+
remedy;
|
|
14
|
+
constructor(code, remedy) {
|
|
15
|
+
super(`${code}: ${remedy}`, 2, { code, nextSteps: [remedy] });
|
|
16
|
+
this.remedy = remedy;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Reject exotic objects before reading untrusted keys or serializing values. */
|
|
20
|
+
function record(value) {
|
|
21
|
+
return value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype;
|
|
22
|
+
}
|
|
23
|
+
/** Require dense, ordinary arrays without additional keys. */
|
|
24
|
+
function dense(value) {
|
|
25
|
+
return Array.isArray(value) && Object.keys(value).length === value.length && Array.from({ length: value.length }, (_, i) => Object.hasOwn(value, i)).every(Boolean);
|
|
26
|
+
}
|
|
27
|
+
/** Bounded JSON domain shared by requests and emitted data, including nested native values. */
|
|
28
|
+
function jsonValue(value, remaining, depth = 0, counters = false, sdk = false) {
|
|
29
|
+
if (--remaining.nodes < 0 || depth > 20)
|
|
30
|
+
return false;
|
|
31
|
+
if (value === null || typeof value === "boolean" || typeof value === "string")
|
|
32
|
+
return true;
|
|
33
|
+
if (typeof value === "number")
|
|
34
|
+
return Number.isFinite(value) && (!counters || (Number.isSafeInteger(value) && value >= 0));
|
|
35
|
+
if (dense(value))
|
|
36
|
+
return value.every((entry) => jsonValue(entry, remaining, depth + 1, counters, sdk));
|
|
37
|
+
// SDK optional object properties may be undefined; ordinary JSON transport
|
|
38
|
+
// omits those keys. Array holes/undefined elements remain invalid everywhere.
|
|
39
|
+
return record(value) && Object.values(value).every((entry) => (sdk && entry === undefined) || jsonValue(entry, remaining, depth + 1, counters, sdk));
|
|
40
|
+
}
|
|
41
|
+
/** All request objects have closed key sets to prevent ignored misspellings. */
|
|
42
|
+
function keys(value, allowed) { return Object.keys(value).every((key) => allowed.includes(key)); }
|
|
43
|
+
/** Portable identifiers are also safe selectors without shell interpolation. */
|
|
44
|
+
function identifier(value) { return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/.test(value); }
|
|
45
|
+
/** Metadata selectors are top-level field names, never paths or facet expressions. */
|
|
46
|
+
function field(value) { return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(value); }
|
|
47
|
+
/** Require bounded unique lists and reject sparse entries before iteration. */
|
|
48
|
+
function list(value, min, max, valid) {
|
|
49
|
+
return dense(value) && value.length >= min && value.length <= max && value.every(valid) && new Set(value).size === value.length;
|
|
50
|
+
}
|
|
51
|
+
/** Narrow an explicit phase, with no inferred task status semantics. */
|
|
52
|
+
function phase(value) { return TASK_PHASES.includes(value); }
|
|
53
|
+
/** Validate untrusted input once before reading sources; never normalize tracker content. */
|
|
54
|
+
export function parsePhaseContextRequest(value) {
|
|
55
|
+
const fail = () => new PhaseContextError("INVALID_REQUEST", "Supply phase, 1-32 unique item ids and contracts for investigation/implementation/review/handoff (1-32 unique top-level fields each). Optional: previous_phase, include_fields (0-32), byte_budget (integer 512-262144), format (json|toon), SDK session (at most 10000 seen ids). Remove unknown keys; use dense arrays and finite numbers.");
|
|
56
|
+
if (!jsonValue(value, { nodes: 20000 }) || Buffer.byteLength(JSON.stringify(value)) > 262144 || !record(value) || !keys(value, ["phase", "contracts", "items", "previous_phase", "include_fields", "byte_budget", "format", "session"]) || !phase(value.phase) || !list(value.items, 1, 32, identifier) || !record(value.contracts) || !keys(value.contracts, TASK_PHASES) || !TASK_PHASES.every((name) => list(value.contracts[name], 1, 32, field)))
|
|
57
|
+
throw fail();
|
|
58
|
+
if ((Object.hasOwn(value, "previous_phase") && !phase(value.previous_phase)) || (Object.hasOwn(value, "include_fields") && !list(value.include_fields, 0, 32, field)) || (Object.hasOwn(value, "format") && value.format !== "json" && value.format !== "toon") || (Object.hasOwn(value, "byte_budget") && (!Number.isSafeInteger(value.byte_budget) || Number(value.byte_budget) < 512 || Number(value.byte_budget) > 262144)))
|
|
59
|
+
throw fail();
|
|
60
|
+
let session;
|
|
61
|
+
if (Object.hasOwn(value, "session")) {
|
|
62
|
+
try {
|
|
63
|
+
if (!record(value.session) || !list(value.session.seen_item_ids, 0, 10000, identifier))
|
|
64
|
+
throw fail();
|
|
65
|
+
session = parseReadOutputSession(value.session);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
throw fail();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const input = value;
|
|
72
|
+
return {
|
|
73
|
+
phase: input.phase, contracts: Object.fromEntries(TASK_PHASES.map((name) => [name, [...input.contracts[name]].sort()])),
|
|
74
|
+
items: [...input.items].sort(),
|
|
75
|
+
...(input.previous_phase === undefined ? {} : { previous_phase: input.previous_phase }),
|
|
76
|
+
include_fields: [...(input.include_fields ?? [])].sort(), byte_budget: input.byte_budget ?? 16000, format: input.format ?? "toon",
|
|
77
|
+
...(session === undefined ? {} : { session }),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** Read bounded regular UTF-8 JSON; the shared builder owns schema validation. */
|
|
81
|
+
export function readPhaseContextJson(path) {
|
|
82
|
+
try {
|
|
83
|
+
return readFreshnessJson(path);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
throw new PhaseContextError("INPUT_UNAVAILABLE", "Supply a stable readable regular UTF-8 JSON request no larger than 262144 bytes.");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Serialize only valid finite JSON data, preserving exact source strings and arrays. */
|
|
90
|
+
export function encodePhaseContext(packet) {
|
|
91
|
+
if (!jsonValue(packet, { nodes: 100000 }, 0, true) || !["json", "toon"].includes(packet.format) || packet.byte_budget < 512 || packet.byte_budget > 262144 || packet.bytes > 262144)
|
|
92
|
+
throw new PhaseContextError("INVALID_OUTPUT", "Regenerate the packet from current SDK reads; output must use json|toon, nonnegative safe counters and byte_budget 512-262144.");
|
|
93
|
+
return `${packet.format === "json" ? JSON.stringify(packet) : encode(packet)}\n`;
|
|
94
|
+
}
|
|
95
|
+
/** Emit recovery only for selectors that preserve the stored metadata meaning. */
|
|
96
|
+
function restoreField(item, name, supported, derived) {
|
|
97
|
+
return supported.has(name)
|
|
98
|
+
? buildRestoreCommand(["pm", "get", item, "--fields", name, "--output-budget", "unbounded", "--json"])
|
|
99
|
+
: { restore_unavailable: { code: "UNSUPPORTED_FIELD_PROJECTION", reason: derived.has(name) ? "The pinned CLI reserves this selector for derived output instead of the stored metadata value. Read this field through the SDK or retain its phase fact; no value-preserving CLI restoration is available." : "The pinned CLI has no supported single-field projection for this source key. Read it through the SDK or include it in a phase packet when the request schema accepts the key." } };
|
|
100
|
+
}
|
|
101
|
+
/** Build mandatory projections using SDK intent resolution, omission receipts and session reuse. */
|
|
102
|
+
export async function buildPhaseContext(input, pmRoot) {
|
|
103
|
+
const request = parsePhaseContextRequest(input);
|
|
104
|
+
const contracts = composeContextIntentContracts([], TASK_PHASES.map((name) => ({ command: "context-phase", intent: name, description: `Mandatory ${name} fields`, included_field_groups: request.contracts[name], token_budget: 65536 })));
|
|
105
|
+
const mandatory = resolveContextIntentContract("context-phase", request.phase, contracts).included_field_groups;
|
|
106
|
+
const included = new Set([...mandatory, ...request.include_fields]);
|
|
107
|
+
const previous = request.previous_phase === undefined ? [] : request.contracts[request.previous_phase];
|
|
108
|
+
const packet = {
|
|
109
|
+
ok: true, protocol: "pm-context-phase/v1", phase: request.phase, previous_phase: request.previous_phase ?? null,
|
|
110
|
+
mandatory_fields: mandatory,
|
|
111
|
+
changes: [...new Set([...previous, ...mandatory])].sort().map((name) => ({ field: name, change: !previous.includes(name) ? "added" : !mandatory.includes(name) ? "removed" : "retained", reason: !previous.includes(name) ? `Required by ${request.phase}` : !mandatory.includes(name) ? `Required by ${request.previous_phase}; optional in ${request.phase}` : `Required by both ${request.previous_phase} and ${request.phase}` })),
|
|
112
|
+
bindings: [], facts: [], omission_receipt: { ...createOutputOmissionReceipt([]), omitted_field_groups: [] }, bytes: 0, byte_budget: request.byte_budget, format: request.format, session_fact_scope: "item-field-value;restore-with-bindings",
|
|
113
|
+
};
|
|
114
|
+
const read = createFreshnessReader(pmRoot, ".");
|
|
115
|
+
let supported;
|
|
116
|
+
let derived;
|
|
117
|
+
try {
|
|
118
|
+
const settings = await read({ kind: "settings" });
|
|
119
|
+
const runtimeKeys = resolveRuntimeFieldRegistry(settings.schema).definitions.map((definition) => definition.metadata_key);
|
|
120
|
+
// Discover reserved output meanings before runtime fields can make a
|
|
121
|
+
// derived selector appear in both advertised domains. Registration cannot
|
|
122
|
+
// change what the core get command actually returns for those names.
|
|
123
|
+
const nativeMetadata = new Set(listListProjectionFields());
|
|
124
|
+
derived = new Set(listGetProjectionFields().filter((name) => !nativeMetadata.has(name)));
|
|
125
|
+
// Aliases select canonical fields, not raw metadata keys containing dots.
|
|
126
|
+
const metadata = new Set(listListProjectionFields(runtimeKeys));
|
|
127
|
+
supported = new Set(listGetProjectionFields(runtimeKeys).filter((name) => field(name) && metadata.has(name) && !derived.has(name)));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new PhaseContextError("SOURCE_UNAVAILABLE", "Restore readable SDK settings before deriving executable field projections.");
|
|
131
|
+
}
|
|
132
|
+
const omitted = [];
|
|
133
|
+
let sourceBytes = 0;
|
|
134
|
+
for (const item of request.items) {
|
|
135
|
+
let source;
|
|
136
|
+
try {
|
|
137
|
+
const value = await read({ kind: "item", id: item });
|
|
138
|
+
if (!record(value) || !jsonValue(value, { nodes: 100000 }, 0, false, true))
|
|
139
|
+
throw new Error();
|
|
140
|
+
const serialized = JSON.stringify(value);
|
|
141
|
+
sourceBytes += Buffer.byteLength(serialized);
|
|
142
|
+
if (sourceBytes > 8388608)
|
|
143
|
+
throw new Error();
|
|
144
|
+
source = JSON.parse(serialized);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
throw new PhaseContextError("SOURCE_UNAVAILABLE", `Restore readable SDK source ${item}, with finite JSON fields; narrow selection to at most 8388608 source bytes. No packet was issued.`);
|
|
148
|
+
}
|
|
149
|
+
for (const name of Object.keys(source).sort())
|
|
150
|
+
if (!included.has(name))
|
|
151
|
+
omitted.push({ name: `${item}.${name}`, ...restoreField(item, name, supported, derived) });
|
|
152
|
+
for (const name of [...included].sort()) {
|
|
153
|
+
if (!Object.hasOwn(source, name))
|
|
154
|
+
throw new PhaseContextError("MISSING_FIELD", `Restore field ${name} on item ${item}, or revise the declared contract/include_fields. No mandatory field was dropped.`);
|
|
155
|
+
const value_json = JSON.stringify(source[name]);
|
|
156
|
+
// This is a read fact identity, not a mutation idempotency key. Include the
|
|
157
|
+
// target coordinate so equal text on different items/fields never aliases.
|
|
158
|
+
const id = `f-${createHash("sha256").update(JSON.stringify([item, name, value_json])).digest("hex")}`;
|
|
159
|
+
packet.bindings.push({ item, field: name, fact: id, mandatory: mandatory.includes(name), ...restoreField(item, name, supported, derived) });
|
|
160
|
+
packet.facts.push({ id, value_json });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
packet.omission_receipt = { ...createOutputOmissionReceipt(omitted.map((group) => ({ name: group.name, restore_with: group.restore_with ?? "" }))), omitted_field_groups: omitted };
|
|
164
|
+
let result = packet;
|
|
165
|
+
if (request.session) {
|
|
166
|
+
result.session_restore = buildSuggestedCommand(["pm", "get", request.items[0], "--fields", "id", "--output-budget", "unbounded", "--json"]);
|
|
167
|
+
// The SDK owns reference construction and receipt accounting. Only facts are
|
|
168
|
+
// rows: bindings and explanations must remain present even when facts reuse.
|
|
169
|
+
const projected = applyReadOutputSessionReferences({ ...packet, row_contract: { command: "context-phase", row_kind: "collection", row_keys: ["facts"], fields: "unsupported" } }, request.session);
|
|
170
|
+
result = { ...packet, facts: projected.facts };
|
|
171
|
+
}
|
|
172
|
+
// Coupled fixed point: exact transport bytes include their own digits and the
|
|
173
|
+
// SDK receipt; SDK accounting intentionally measures the compact JSON object.
|
|
174
|
+
for (;;) {
|
|
175
|
+
if (request.session) {
|
|
176
|
+
const accounted = attachReadOutputSessionReceipt({ ...result }, request.session);
|
|
177
|
+
// The SDK's legacy display template is not executable POSIX text. Account
|
|
178
|
+
// it conservatively, but emit only our structured, quoted replacement.
|
|
179
|
+
const read_session = Object.fromEntries(Object.entries(accounted.read_session).filter(([key]) => key !== "restore_reference_with"));
|
|
180
|
+
result = { ...accounted, read_session };
|
|
181
|
+
}
|
|
182
|
+
const bytes = Buffer.byteLength(encodePhaseContext(result));
|
|
183
|
+
if (bytes > result.byte_budget || (result.read_session && result.read_session.spent_this_call_tokens > request.session.token_budget - request.session.spent_tokens))
|
|
184
|
+
throw new PhaseContextError("BUDGET_TOO_SMALL", "Increase byte_budget or the SDK session token budget, narrow items, or start a fresh session. Mandatory facts and complete receipts must all fit; no session state was advanced.");
|
|
185
|
+
if (bytes === result.bytes)
|
|
186
|
+
return result;
|
|
187
|
+
result.bytes = bytes;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=task-phase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-phase.js","sourceRoot":"","sources":["../task-phase.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pm-context",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.28",
|
|
4
4
|
"description": "Generate deterministic pm context packs for agent handoffs, reviews, and status briefs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"build:test": "tsc -p tsconfig.test.json",
|
|
18
|
-
"test": "npm run build && npm run build:test && node --test test/*.test.ts",
|
|
18
|
+
"test": "npm run build && npm run build:test && node --test --test-concurrency=2 test/*.test.ts",
|
|
19
19
|
"prepack": "npm run build",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
21
|
"check": "npm run typecheck",
|
|
@@ -40,13 +40,16 @@
|
|
|
40
40
|
"handoff",
|
|
41
41
|
"project-management"
|
|
42
42
|
],
|
|
43
|
-
"author":
|
|
43
|
+
"author": {
|
|
44
|
+
"name": "unbrained",
|
|
45
|
+
"url": "https://unbrained.dev/about"
|
|
46
|
+
},
|
|
44
47
|
"license": "MIT",
|
|
45
48
|
"repository": {
|
|
46
49
|
"type": "git",
|
|
47
50
|
"url": "git+https://github.com/unbraind/pm-context.git"
|
|
48
51
|
},
|
|
49
|
-
"homepage": "https://
|
|
52
|
+
"homepage": "https://pm-cli.unbrained.dev/packages/pm-context",
|
|
50
53
|
"bugs": {
|
|
51
54
|
"url": "https://github.com/unbraind/pm-context/issues"
|
|
52
55
|
},
|
|
@@ -55,10 +58,10 @@
|
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@types/node": "26.6.5",
|
|
58
|
-
"@unbrained/pm-cli": "2026.10.
|
|
61
|
+
"@unbrained/pm-cli": "2026.10.24",
|
|
59
62
|
"c8": "12.0.0",
|
|
60
|
-
"pm-changelog": "2026.10.
|
|
61
|
-
"pm-ops": "2026.10.
|
|
63
|
+
"pm-changelog": "2026.10.24",
|
|
64
|
+
"pm-ops": "2026.10.24",
|
|
62
65
|
"typescript": "7.0.2",
|
|
63
66
|
"yaml": "2.9.1"
|
|
64
67
|
},
|
|
@@ -120,5 +123,8 @@
|
|
|
120
123
|
"branches": 99.9,
|
|
121
124
|
"functions": 100,
|
|
122
125
|
"lines": 100
|
|
126
|
+
},
|
|
127
|
+
"dependencies": {
|
|
128
|
+
"@toon-format/toon": "4.4.0"
|
|
123
129
|
}
|
|
124
130
|
}
|