@telora/daemon 0.16.44 → 0.17.2
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/build-info.json +6 -3
- package/dist/completion/event.d.ts +17 -0
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +46 -12
- package/dist/completion/event.js.map +1 -1
- package/dist/escalations.d.ts +38 -0
- package/dist/escalations.d.ts.map +1 -0
- package/dist/escalations.js +38 -0
- package/dist/escalations.js.map +1 -0
- package/dist/focus-engine.d.ts.map +1 -1
- package/dist/focus-engine.js +28 -0
- package/dist/focus-engine.js.map +1 -1
- package/dist/prd-clearance-engine.d.ts +121 -0
- package/dist/prd-clearance-engine.d.ts.map +1 -0
- package/dist/prd-clearance-engine.js +164 -0
- package/dist/prd-clearance-engine.js.map +1 -0
- package/dist/prd-controller.d.ts +87 -0
- package/dist/prd-controller.d.ts.map +1 -0
- package/dist/prd-controller.js +319 -0
- package/dist/prd-controller.js.map +1 -0
- package/dist/prd-divergence.d.ts +76 -0
- package/dist/prd-divergence.d.ts.map +1 -0
- package/dist/prd-divergence.js +148 -0
- package/dist/prd-divergence.js.map +1 -0
- package/dist/queries/prd.d.ts +79 -0
- package/dist/queries/prd.d.ts.map +1 -0
- package/dist/queries/prd.js +116 -0
- package/dist/queries/prd.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD divergence detection + path selection -- Staged Assembly: PRD Layer
|
|
3
|
+
* (Delivery E, task E1). PURE: no DB, no shell, no module-level mutable state.
|
|
4
|
+
*
|
|
5
|
+
* PLL framing. The committed pathway is the locked phase. Divergence is loss of
|
|
6
|
+
* lock -- the chosen approach stopped tracking intent. Path-switch is re-capture
|
|
7
|
+
* onto the best surviving path computed from ACTUAL current tree state. When no
|
|
8
|
+
* survivor exists the controller escalates to the human, who owns intent.
|
|
9
|
+
*
|
|
10
|
+
* NO-REVERT INVARIANT (read before editing). Dead-path residue -- code already
|
|
11
|
+
* merged on a now-abandoned pathway -- is NEW REALITY, not garbage to undo.
|
|
12
|
+
* Nothing in this module (or the realign step that consumes it) reverts, deletes,
|
|
13
|
+
* or rolls back focuses, commits, or merged work. Detection reads the tree;
|
|
14
|
+
* selection re-points which pathway is committed. The goal is never lowered to
|
|
15
|
+
* fit a path; we only re-acquire a path that still reaches the goal, or escalate.
|
|
16
|
+
*
|
|
17
|
+
* @module prd-divergence
|
|
18
|
+
*/
|
|
19
|
+
import type { PrtNode, PrtEdge } from './queries/prd.js';
|
|
20
|
+
/** The shapes divergence can take on a Prerequisite Tree. */
|
|
21
|
+
export type DivergenceForm = 'clearance_fail' | 'negative_branch' | 'falsified_prerequisite';
|
|
22
|
+
/** A single detected divergence, anchored to the offending node. */
|
|
23
|
+
export interface DivergenceSignal {
|
|
24
|
+
form: DivergenceForm;
|
|
25
|
+
nodeId: string;
|
|
26
|
+
detail: string;
|
|
27
|
+
}
|
|
28
|
+
/** A held alternative pathway and its commitment status. */
|
|
29
|
+
export interface PathwayState {
|
|
30
|
+
id: string;
|
|
31
|
+
status: 'option' | 'committed' | 'abandoned';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Detect all divergence signals on a PRT snapshot. PURE. A healthy path
|
|
35
|
+
* returns []. Implements all three forms:
|
|
36
|
+
*
|
|
37
|
+
* - clearance_fail: an overcome O marked cleared (shipped) whose 'overcomes'
|
|
38
|
+
* edge O->B points at an obstacle B that did NOT clear this tick
|
|
39
|
+
* (B in clearanceFailedObstacleIds). The remedy ran but the obstacle stands.
|
|
40
|
+
*
|
|
41
|
+
* - negative_branch: an OPEN obstacle B (status !== 'cleared') with NO inbound
|
|
42
|
+
* 'overcomes' edge (no planned remedy) that is a prerequisite (edge B->Q) of
|
|
43
|
+
* some overcome Q which is not cleared. An unanticipated blocker on the path.
|
|
44
|
+
*
|
|
45
|
+
* - falsified_prerequisite: a 'prerequisite' edge P->Q where Q is cleared but
|
|
46
|
+
* P is not. Downstream proceeded though its prerequisite is unsatisfied.
|
|
47
|
+
*/
|
|
48
|
+
export declare function detectDivergence(input: {
|
|
49
|
+
nodes: PrtNode[];
|
|
50
|
+
edges: PrtEdge[];
|
|
51
|
+
clearedNodeIds: Set<string>;
|
|
52
|
+
clearanceFailedObstacleIds: Set<string>;
|
|
53
|
+
committedPathwayId: string | null;
|
|
54
|
+
}): DivergenceSignal[];
|
|
55
|
+
/**
|
|
56
|
+
* Select the surviving committed pathway. PURE.
|
|
57
|
+
*
|
|
58
|
+
* Among pathways that are NOT abandoned:
|
|
59
|
+
* - If a committed pathway is set and still viable, keep it
|
|
60
|
+
* (survivor = committed, switched = false). Lock held.
|
|
61
|
+
* - Otherwise pick the first viable non-abandoned pathway; switched = true when
|
|
62
|
+
* that survivor differs from the previously committed pathway. Re-capture.
|
|
63
|
+
* - If none are viable, survivor = null, switched = false. The controller
|
|
64
|
+
* escalates -- the human owns intent; the goal is never lowered.
|
|
65
|
+
*
|
|
66
|
+
* NO-REVERT: choosing a different survivor only changes which pathway is
|
|
67
|
+
* committed. It never undoes work done on the abandoned/old pathway.
|
|
68
|
+
*/
|
|
69
|
+
export declare function selectSurvivingPath(pathways: PathwayState[], opts: {
|
|
70
|
+
committedPathwayId: string | null;
|
|
71
|
+
isPathwayViable: (pathwayId: string) => boolean;
|
|
72
|
+
}): {
|
|
73
|
+
survivor: string | null;
|
|
74
|
+
switched: boolean;
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=prd-divergence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd-divergence.d.ts","sourceRoot":"","sources":["../src/prd-divergence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAMzD,6DAA6D;AAC7D,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,iBAAiB,GACjB,wBAAwB,CAAC;AAE7B,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;CAC9C;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,0BAA0B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,GAAG,gBAAgB,EAAE,CAsFrB;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EAAE,EACxB,IAAI,EAAE;IACJ,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CACjD,GACA;IAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAyBhD"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD divergence detection + path selection -- Staged Assembly: PRD Layer
|
|
3
|
+
* (Delivery E, task E1). PURE: no DB, no shell, no module-level mutable state.
|
|
4
|
+
*
|
|
5
|
+
* PLL framing. The committed pathway is the locked phase. Divergence is loss of
|
|
6
|
+
* lock -- the chosen approach stopped tracking intent. Path-switch is re-capture
|
|
7
|
+
* onto the best surviving path computed from ACTUAL current tree state. When no
|
|
8
|
+
* survivor exists the controller escalates to the human, who owns intent.
|
|
9
|
+
*
|
|
10
|
+
* NO-REVERT INVARIANT (read before editing). Dead-path residue -- code already
|
|
11
|
+
* merged on a now-abandoned pathway -- is NEW REALITY, not garbage to undo.
|
|
12
|
+
* Nothing in this module (or the realign step that consumes it) reverts, deletes,
|
|
13
|
+
* or rolls back focuses, commits, or merged work. Detection reads the tree;
|
|
14
|
+
* selection re-points which pathway is committed. The goal is never lowered to
|
|
15
|
+
* fit a path; we only re-acquire a path that still reaches the goal, or escalate.
|
|
16
|
+
*
|
|
17
|
+
* @module prd-divergence
|
|
18
|
+
*/
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Divergence detection
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Detect all divergence signals on a PRT snapshot. PURE. A healthy path
|
|
24
|
+
* returns []. Implements all three forms:
|
|
25
|
+
*
|
|
26
|
+
* - clearance_fail: an overcome O marked cleared (shipped) whose 'overcomes'
|
|
27
|
+
* edge O->B points at an obstacle B that did NOT clear this tick
|
|
28
|
+
* (B in clearanceFailedObstacleIds). The remedy ran but the obstacle stands.
|
|
29
|
+
*
|
|
30
|
+
* - negative_branch: an OPEN obstacle B (status !== 'cleared') with NO inbound
|
|
31
|
+
* 'overcomes' edge (no planned remedy) that is a prerequisite (edge B->Q) of
|
|
32
|
+
* some overcome Q which is not cleared. An unanticipated blocker on the path.
|
|
33
|
+
*
|
|
34
|
+
* - falsified_prerequisite: a 'prerequisite' edge P->Q where Q is cleared but
|
|
35
|
+
* P is not. Downstream proceeded though its prerequisite is unsatisfied.
|
|
36
|
+
*/
|
|
37
|
+
export function detectDivergence(input) {
|
|
38
|
+
const { nodes, edges, clearedNodeIds, clearanceFailedObstacleIds } = input;
|
|
39
|
+
const signals = [];
|
|
40
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
41
|
+
const overcomesEdges = edges.filter((e) => e.edgeType === 'overcomes');
|
|
42
|
+
const prereqEdges = edges.filter((e) => e.edgeType === 'prerequisite');
|
|
43
|
+
// --- clearance_fail ---
|
|
44
|
+
// An overcome that is cleared but the obstacle it overcomes did not clear.
|
|
45
|
+
for (const edge of overcomesEdges) {
|
|
46
|
+
const overcome = nodeById.get(edge.fromNodeId);
|
|
47
|
+
const obstacle = nodeById.get(edge.toNodeId);
|
|
48
|
+
if (!overcome || !obstacle) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (overcome.nodeType !== 'overcome' || overcome.status !== 'cleared') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (clearanceFailedObstacleIds.has(obstacle.id)) {
|
|
55
|
+
signals.push({
|
|
56
|
+
form: 'clearance_fail',
|
|
57
|
+
nodeId: obstacle.id,
|
|
58
|
+
detail: `overcome ${overcome.id} is cleared (shipped) but obstacle ${obstacle.id} ` +
|
|
59
|
+
`failed its clearance predicate this tick`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// --- negative_branch ---
|
|
64
|
+
// An open obstacle with no planned remedy that gates an uncleared overcome.
|
|
65
|
+
const obstaclesWithRemedy = new Set(overcomesEdges.map((e) => e.toNodeId));
|
|
66
|
+
for (const node of nodes) {
|
|
67
|
+
if (node.nodeType !== 'obstacle') {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (node.status === 'cleared') {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (obstaclesWithRemedy.has(node.id)) {
|
|
74
|
+
continue; // a remedy is planned -> anticipated, not a negative branch
|
|
75
|
+
}
|
|
76
|
+
// Is this obstacle a prerequisite of an uncleared overcome?
|
|
77
|
+
const gatesUnclearedOvercome = prereqEdges.some((edge) => {
|
|
78
|
+
if (edge.fromNodeId !== node.id) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const target = nodeById.get(edge.toNodeId);
|
|
82
|
+
return (!!target &&
|
|
83
|
+
target.nodeType === 'overcome' &&
|
|
84
|
+
!clearedNodeIds.has(target.id));
|
|
85
|
+
});
|
|
86
|
+
if (gatesUnclearedOvercome) {
|
|
87
|
+
signals.push({
|
|
88
|
+
form: 'negative_branch',
|
|
89
|
+
nodeId: node.id,
|
|
90
|
+
detail: `obstacle ${node.id} is open with no planned overcome and gates an ` +
|
|
91
|
+
`uncleared overcome -- unanticipated blocker`,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// --- falsified_prerequisite ---
|
|
96
|
+
// A prerequisite edge whose downstream cleared while its upstream did not.
|
|
97
|
+
for (const edge of prereqEdges) {
|
|
98
|
+
if (clearedNodeIds.has(edge.toNodeId) &&
|
|
99
|
+
!clearedNodeIds.has(edge.fromNodeId)) {
|
|
100
|
+
signals.push({
|
|
101
|
+
form: 'falsified_prerequisite',
|
|
102
|
+
nodeId: edge.fromNodeId,
|
|
103
|
+
detail: `node ${edge.toNodeId} is cleared but its prerequisite ${edge.fromNodeId} ` +
|
|
104
|
+
`is not -- downstream proceeded on an unsatisfied prerequisite`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return signals;
|
|
109
|
+
}
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Surviving-path selection (re-capture)
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
/**
|
|
114
|
+
* Select the surviving committed pathway. PURE.
|
|
115
|
+
*
|
|
116
|
+
* Among pathways that are NOT abandoned:
|
|
117
|
+
* - If a committed pathway is set and still viable, keep it
|
|
118
|
+
* (survivor = committed, switched = false). Lock held.
|
|
119
|
+
* - Otherwise pick the first viable non-abandoned pathway; switched = true when
|
|
120
|
+
* that survivor differs from the previously committed pathway. Re-capture.
|
|
121
|
+
* - If none are viable, survivor = null, switched = false. The controller
|
|
122
|
+
* escalates -- the human owns intent; the goal is never lowered.
|
|
123
|
+
*
|
|
124
|
+
* NO-REVERT: choosing a different survivor only changes which pathway is
|
|
125
|
+
* committed. It never undoes work done on the abandoned/old pathway.
|
|
126
|
+
*/
|
|
127
|
+
export function selectSurvivingPath(pathways, opts) {
|
|
128
|
+
const candidates = pathways.filter((p) => p.status !== 'abandoned');
|
|
129
|
+
// Keep the committed path if it is still in play and viable.
|
|
130
|
+
if (opts.committedPathwayId !== null) {
|
|
131
|
+
const committedStillCandidate = candidates.some((p) => p.id === opts.committedPathwayId);
|
|
132
|
+
if (committedStillCandidate && opts.isPathwayViable(opts.committedPathwayId)) {
|
|
133
|
+
return { survivor: opts.committedPathwayId, switched: false };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Otherwise re-acquire the first viable surviving option.
|
|
137
|
+
for (const pathway of candidates) {
|
|
138
|
+
if (opts.isPathwayViable(pathway.id)) {
|
|
139
|
+
return {
|
|
140
|
+
survivor: pathway.id,
|
|
141
|
+
switched: pathway.id !== opts.committedPathwayId,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// No survivor: hand control to the human.
|
|
146
|
+
return { survivor: null, switched: false };
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=prd-divergence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd-divergence.js","sourceRoot":"","sources":["../src/prd-divergence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin callApi wrappers for PRD / Prerequisite-Tree (PRT) data (Delivery D).
|
|
3
|
+
*
|
|
4
|
+
* Maps the snake_case product-api response shapes (see
|
|
5
|
+
* supabase/functions/product-api/handlers/prd/*) onto camelCase daemon types.
|
|
6
|
+
* No business logic lives here -- it is a transport seam the controller injects.
|
|
7
|
+
*
|
|
8
|
+
* The product-api transformers already camelCase most fields (transformPrd,
|
|
9
|
+
* transformPrtNode, transformPrtEdge), so these wrappers re-shape the already
|
|
10
|
+
* camelCased response into the narrow controller-facing types and drop fields
|
|
11
|
+
* the controller does not consume.
|
|
12
|
+
*/
|
|
13
|
+
import type { ClearancePredicate } from '../prd-clearance-engine.js';
|
|
14
|
+
export interface PrtNode {
|
|
15
|
+
id: string;
|
|
16
|
+
prdId: string;
|
|
17
|
+
nodeType: 'goal' | 'obstacle' | 'overcome';
|
|
18
|
+
status: 'open' | 'cleared';
|
|
19
|
+
clearancePredicate: ClearancePredicate | null;
|
|
20
|
+
focusId: string | null;
|
|
21
|
+
}
|
|
22
|
+
export interface PrtEdge {
|
|
23
|
+
id: string;
|
|
24
|
+
fromNodeId: string;
|
|
25
|
+
toNodeId: string;
|
|
26
|
+
edgeType: 'prerequisite' | 'overcomes';
|
|
27
|
+
}
|
|
28
|
+
export interface Prd {
|
|
29
|
+
id: string;
|
|
30
|
+
productId: string;
|
|
31
|
+
status: string;
|
|
32
|
+
title: string;
|
|
33
|
+
/** The pathway currently committed (locked) for this PRD, or null if none. */
|
|
34
|
+
committedPathId: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** A held alternative pathway under a PRD (option / committed / abandoned). */
|
|
37
|
+
export interface Pathway {
|
|
38
|
+
id: string;
|
|
39
|
+
prdId: string;
|
|
40
|
+
status: 'option' | 'committed' | 'abandoned';
|
|
41
|
+
name: string;
|
|
42
|
+
}
|
|
43
|
+
/** List active PRDs for a product (prd_list returns { items }). */
|
|
44
|
+
export declare function loadActivePrds(productId: string): Promise<Prd[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Load a PRD's full PRT graph. prd_get returns { prd: { ...prd, nodes, edges } }.
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadPrtGraph(prdId: string): Promise<{
|
|
49
|
+
nodes: PrtNode[];
|
|
50
|
+
edges: PrtEdge[];
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Materialize an overcome into a focus. prd_overcome_materialize returns
|
|
54
|
+
* { focus, nodeId } where focus is a raw product_focuses row (snake_case id).
|
|
55
|
+
*/
|
|
56
|
+
export declare function materializeOvercome(nodeId: string): Promise<{
|
|
57
|
+
focusId: string;
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Arm a focus via the existing queue toggle (focus_update sets
|
|
61
|
+
* assigned_agent_role_id). The fields wrapper matches the focus_update handler.
|
|
62
|
+
*/
|
|
63
|
+
export declare function armFocus(focusId: string, agentRoleId: string): Promise<void>;
|
|
64
|
+
/** Mark a PRT node cleared (prd_prt_node_update param is nodeId). */
|
|
65
|
+
export declare function markNodeCleared(nodeId: string): Promise<void>;
|
|
66
|
+
/** Mark a PRD done (prd_update param is prdId). */
|
|
67
|
+
export declare function markPrdDone(prdId: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* List the held pathways for a PRD (prd_pathway_list returns { items }).
|
|
70
|
+
* Pathways are the alternative approaches the controller switches between on
|
|
71
|
+
* divergence; one is committed (locked) at a time.
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadPathways(prdId: string): Promise<Pathway[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Commit (lock) a pathway for a PRD. Re-points which pathway is committed --
|
|
76
|
+
* NO revert: this never undoes work already done on a prior pathway.
|
|
77
|
+
*/
|
|
78
|
+
export declare function commitPathway(prdId: string, pathwayId: string): Promise<void>;
|
|
79
|
+
//# sourceMappingURL=prd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/queries/prd.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAC3C,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,GAAG,WAAW,CAAC;CACxC;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,+EAA+E;AAC/E,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AA0ED,mEAAmE;AACnE,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAMtE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAUjD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAStF;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlF;AAED,qEAAqE;AACrE,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,mDAAmD;AACnD,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAKpE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin callApi wrappers for PRD / Prerequisite-Tree (PRT) data (Delivery D).
|
|
3
|
+
*
|
|
4
|
+
* Maps the snake_case product-api response shapes (see
|
|
5
|
+
* supabase/functions/product-api/handlers/prd/*) onto camelCase daemon types.
|
|
6
|
+
* No business logic lives here -- it is a transport seam the controller injects.
|
|
7
|
+
*
|
|
8
|
+
* The product-api transformers already camelCase most fields (transformPrd,
|
|
9
|
+
* transformPrtNode, transformPrtEdge), so these wrappers re-shape the already
|
|
10
|
+
* camelCased response into the narrow controller-facing types and drop fields
|
|
11
|
+
* the controller does not consume.
|
|
12
|
+
*/
|
|
13
|
+
import { callApi } from './shared.js';
|
|
14
|
+
function mapPrd(row) {
|
|
15
|
+
return {
|
|
16
|
+
id: row.id,
|
|
17
|
+
productId: row.productId,
|
|
18
|
+
status: row.status,
|
|
19
|
+
title: row.title,
|
|
20
|
+
committedPathId: row.committedPathId ?? null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function mapPathway(row) {
|
|
24
|
+
return {
|
|
25
|
+
id: row.id,
|
|
26
|
+
prdId: row.prdId,
|
|
27
|
+
status: row.status,
|
|
28
|
+
name: row.name,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function mapNode(row) {
|
|
32
|
+
return {
|
|
33
|
+
id: row.id,
|
|
34
|
+
prdId: row.prdId,
|
|
35
|
+
nodeType: row.nodeType,
|
|
36
|
+
status: row.status,
|
|
37
|
+
clearancePredicate: row.clearancePredicate ?? null,
|
|
38
|
+
focusId: row.focusId ?? null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function mapEdge(row) {
|
|
42
|
+
return {
|
|
43
|
+
id: row.id,
|
|
44
|
+
fromNodeId: row.fromNodeId,
|
|
45
|
+
toNodeId: row.toNodeId,
|
|
46
|
+
edgeType: row.edgeType,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** List active PRDs for a product (prd_list returns { items }). */
|
|
50
|
+
export async function loadActivePrds(productId) {
|
|
51
|
+
const body = await callApi('prd_list', {
|
|
52
|
+
productId,
|
|
53
|
+
status: 'active',
|
|
54
|
+
});
|
|
55
|
+
return (body.items ?? []).map(mapPrd);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load a PRD's full PRT graph. prd_get returns { prd: { ...prd, nodes, edges } }.
|
|
59
|
+
*/
|
|
60
|
+
export async function loadPrtGraph(prdId) {
|
|
61
|
+
const body = await callApi('prd_get', { prdId });
|
|
62
|
+
const nodes = body.prd?.nodes ?? [];
|
|
63
|
+
const edges = body.prd?.edges ?? [];
|
|
64
|
+
return {
|
|
65
|
+
nodes: nodes.map(mapNode),
|
|
66
|
+
edges: edges.map(mapEdge),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Materialize an overcome into a focus. prd_overcome_materialize returns
|
|
71
|
+
* { focus, nodeId } where focus is a raw product_focuses row (snake_case id).
|
|
72
|
+
*/
|
|
73
|
+
export async function materializeOvercome(nodeId) {
|
|
74
|
+
const body = await callApi('prd_overcome_materialize', { nodeId });
|
|
75
|
+
if (!body.focus?.id) {
|
|
76
|
+
throw new Error(`prd_overcome_materialize returned no focus for node ${nodeId}`);
|
|
77
|
+
}
|
|
78
|
+
return { focusId: body.focus.id };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Arm a focus via the existing queue toggle (focus_update sets
|
|
82
|
+
* assigned_agent_role_id). The fields wrapper matches the focus_update handler.
|
|
83
|
+
*/
|
|
84
|
+
export async function armFocus(focusId, agentRoleId) {
|
|
85
|
+
await callApi('focus_update', {
|
|
86
|
+
focusId,
|
|
87
|
+
fields: { assignedAgentRoleId: agentRoleId },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/** Mark a PRT node cleared (prd_prt_node_update param is nodeId). */
|
|
91
|
+
export async function markNodeCleared(nodeId) {
|
|
92
|
+
await callApi('prd_prt_node_update', { nodeId, status: 'cleared' });
|
|
93
|
+
}
|
|
94
|
+
/** Mark a PRD done (prd_update param is prdId). */
|
|
95
|
+
export async function markPrdDone(prdId) {
|
|
96
|
+
await callApi('prd_update', { prdId, status: 'done' });
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* List the held pathways for a PRD (prd_pathway_list returns { items }).
|
|
100
|
+
* Pathways are the alternative approaches the controller switches between on
|
|
101
|
+
* divergence; one is committed (locked) at a time.
|
|
102
|
+
*/
|
|
103
|
+
export async function loadPathways(prdId) {
|
|
104
|
+
const body = await callApi('prd_pathway_list', {
|
|
105
|
+
prdId,
|
|
106
|
+
});
|
|
107
|
+
return (body.items ?? []).map(mapPathway);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Commit (lock) a pathway for a PRD. Re-points which pathway is committed --
|
|
111
|
+
* NO revert: this never undoes work already done on a prior pathway.
|
|
112
|
+
*/
|
|
113
|
+
export async function commitPathway(prdId, pathwayId) {
|
|
114
|
+
await callApi('prd_pathway_commit', { prdId, pathwayId });
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=prd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd.js","sourceRoot":"","sources":["../../src/queries/prd.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telora/daemon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.2",
|
|
4
4
|
"description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"//testRunner": "Uses Node.js built-in test runner (node:test) via tsx for TypeScript support. The root package uses Vitest; this is a deliberate choice for the daemon package to avoid framework dependencies. See src/__tests__/ for test files.",
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@telora/daemon-core": "^0.2.28",
|
|
40
|
-
"@telora/mcp-products": "^0.22.
|
|
40
|
+
"@telora/mcp-products": "^0.22.38",
|
|
41
41
|
"commander": "^14.0.3",
|
|
42
42
|
"yaml": "^2.4.0",
|
|
43
43
|
"zod": "^4.3.6"
|