ftown 0.27.0 → 0.28.0

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.
Files changed (46) hide show
  1. package/dist/command-rpc.d.ts +11 -0
  2. package/dist/command-rpc.js +79 -15
  3. package/dist/command-rpc.js.map +1 -1
  4. package/dist/coordination/board.js +82 -3
  5. package/dist/coordination/board.js.map +1 -1
  6. package/dist/coordination/contract-c.d.ts +117 -0
  7. package/dist/coordination/contract-c.js +47 -0
  8. package/dist/coordination/contract-c.js.map +1 -0
  9. package/dist/coordination/contract.d.ts +8 -1
  10. package/dist/coordination/contract.js +1 -1
  11. package/dist/coordination/contract.js.map +1 -1
  12. package/dist/coordination/format.js +37 -11
  13. package/dist/coordination/format.js.map +1 -1
  14. package/dist/coordination/plan.d.ts +74 -0
  15. package/dist/coordination/plan.js +534 -0
  16. package/dist/coordination/plan.js.map +1 -0
  17. package/dist/coordination/routes-plan.d.ts +13 -0
  18. package/dist/coordination/routes-plan.js +182 -0
  19. package/dist/coordination/routes-plan.js.map +1 -0
  20. package/dist/coordination/wiring.d.ts +6 -0
  21. package/dist/coordination/wiring.js +50 -2
  22. package/dist/coordination/wiring.js.map +1 -1
  23. package/dist/coordination-cli.d.ts +6 -1
  24. package/dist/coordination-cli.js +17 -7
  25. package/dist/coordination-cli.js.map +1 -1
  26. package/dist/create-ftown-session.d.ts +18 -0
  27. package/dist/create-ftown-session.js +44 -0
  28. package/dist/create-ftown-session.js.map +1 -1
  29. package/dist/ftown-cli.js +5 -2
  30. package/dist/ftown-cli.js.map +1 -1
  31. package/dist/index.js +25 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/local-api-server.js +14 -4
  34. package/dist/local-api-server.js.map +1 -1
  35. package/dist/plan-cli.d.ts +52 -0
  36. package/dist/plan-cli.js +357 -0
  37. package/dist/plan-cli.js.map +1 -0
  38. package/dist/security/bridge/permissions.js +21 -1
  39. package/dist/security/bridge/permissions.js.map +1 -1
  40. package/dist/sessions-commands.js +10 -0
  41. package/dist/sessions-commands.js.map +1 -1
  42. package/dist/types.d.ts +4 -1
  43. package/package.json +2 -2
  44. package/skills/ftown/SKILL.md +42 -0
  45. package/skills/ftown/references/orchestrator.md +29 -25
  46. package/skills/ftown/references/sessions.md +64 -4
@@ -0,0 +1,47 @@
1
+ // ───────────────────────── Plan (todo list with precedence) ─────────────────────────
2
+ export const PLAN_LIMITS = { items: 200, title: 140, note: 500, after: 20 };
3
+ export const PLAN_STATES = ['todo', 'started', 'done', 'dropped'];
4
+ /**
5
+ * Derived ordering (pure helper `orderPlan(items)` in bridge/src/coordination/plan.ts, also re-implemented
6
+ * identically in the UI — see PLAN_ORDER_RULE):
7
+ * ready = state 'todo' && every `after` item is 'done' or 'dropped'
8
+ * waiting = state 'todo' && not ready
9
+ * Order: ready (priority asc, createdAt asc), then waiting (same), then started (updatedAt asc),
10
+ * then done (updatedAt desc), then dropped (updatedAt desc).
11
+ */
12
+ export const PLAN_ORDER_RULE = 'ready>waiting>started>done>dropped; within ready/waiting: priority asc, createdAt asc';
13
+ /** Routes (via dispatchSecure; :id = parent session). Caller: local-cli principal; any session may edit the plan of :id (owner-only enforcement is out of scope). */
14
+ export const PLAN_ROUTES = {
15
+ /** GET → PlanView; POST body { title, note?, after?, priority? } → { item } */
16
+ plan: '/api/sessions/:id/plan',
17
+ /** PATCH body { title?, note?: string|null, after?, priority?, state?, sessionId?: string|null } → { item }; DELETE → { ok: true } (removes id from others' `after`) */
18
+ item: '/api/sessions/:id/plan/:itemId',
19
+ };
20
+ export class PlanValidationError extends Error {
21
+ constructor(message) { super(message); this.name = 'PlanValidationError'; }
22
+ }
23
+ /**
24
+ * Automatic transitions (bridge wiring):
25
+ * - `ftown sessions create --parent --plan-item <id>`: after the child exists, item.state = 'started', item.sessionId = child.id.
26
+ * Unknown/non-todo item → create fails 400 BEFORE the session is created.
27
+ * - When a child's declared card becomes 'done' and an item of its parent has sessionId === child.id and state 'started' → 'done'.
28
+ * 'failed' card → item back to 'todo' with sessionId cleared? NO: leave 'started' (manager decides).
29
+ * - Every plan change emits ONE tree event kind 'plan' on the parent's log with summary
30
+ * `<id> <state>: <title>` ; when items become ready because of it, append ` → ready: <id>, <id>`.
31
+ *
32
+ * CLI (bridge/src/plan-cli.ts, group `ftown plan`, default session = FTOWN_SESSION_ID = the manager):
33
+ * ftown plan [--json] [--session-id <id>] list in order: `<mark> <id> [P<prio>] <title> (after p1,p2 | → <child name>)`
34
+ * marks: `→` ready, `·` waiting, `▸` started, `✓` done, `✗` dropped
35
+ * ftown plan add <title...> [--note <t>] [--after <id,id>] [--priority 1|2|3]
36
+ * ftown plan start <id> --session <child-id>
37
+ * ftown plan done <id> | drop <id> | todo <id>
38
+ * ftown plan edit <id> [--title <t>] [--note <t>|--no-note] [--after <ids>|--no-after] [--priority n]
39
+ * ftown plan rm <id>
40
+ * ftown sessions create --parent --plan-item <id> ... (in sessions-commands.ts)
41
+ * Exit codes: 0 ok, 1 error, 2 usage.
42
+ */
43
+ // ───────────────────────── Tree events: new kinds ─────────────────────────
44
+ /** Added to TREE_EVENT_KINDS in contract.ts (phase C edit): 'plan' and 'removed'. */
45
+ export const PHASE_C_EVENT_KINDS = ['plan', 'removed'];
46
+ export const BOARD_SNAPSHOT_EVENTS = 50;
47
+ //# sourceMappingURL=contract-c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-c.js","sourceRoot":"","sources":["../../src/coordination/contract-c.ts"],"names":[],"mappings":"AAQA,uFAAuF;AAEvF,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAW,CAAC;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AAmB3E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,uFAAgG,CAAC;AAIhI,qKAAqK;AACrK,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,+EAA+E;IAC/E,IAAI,EAAE,wBAAwB;IAC9B,wKAAwK;IACxK,IAAI,EAAE,gCAAgC;CAC9B,CAAC;AAEX,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,CAAC,CAAC;CACpF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,6EAA6E;AAE7E,qFAAqF;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,SAAS,CAAU,CAAC;AA6BhE,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { Activity } from '../attention-events.js';
7
7
  import type { PullRequestState } from '../pull-request-status-protocol.js';
8
+ import type { PlanView } from './contract-c.js';
8
9
  import type { MailMessage, Session, SessionStatus } from '../types.js';
9
10
  export declare const CARD_STATES: readonly ["working", "blocked", "waiting_review", "done", "failed"];
10
11
  export type CardState = typeof CARD_STATES[number];
@@ -70,6 +71,8 @@ export interface CardDerived {
70
71
  model?: string;
71
72
  }
72
73
  export interface SessionCard {
74
+ /** phase C: true for retired (archived) children included by board(all) */
75
+ archived?: boolean;
73
76
  sessionId: string;
74
77
  name: string;
75
78
  parentSessionId?: string;
@@ -99,7 +102,7 @@ export declare const TREE_EVENTS_RETAIN = 5000;
99
102
  export declare const TREE_EVENTS_COMPACT_AT = 6000;
100
103
  export declare const TREE_EVENTS_MAX_WAIT_MS = 300000;
101
104
  export declare const TREE_EVENT_SUMMARY_MAX = 300;
102
- export declare const TREE_EVENT_KINDS: readonly ["status", "attention", "pr", "preview", "exit", "idle", "result", "mail"];
105
+ export declare const TREE_EVENT_KINDS: readonly ["status", "attention", "pr", "preview", "exit", "idle", "result", "mail", "plan", "removed"];
103
106
  export type TreeEventKind = typeof TREE_EVENT_KINDS[number];
104
107
  export interface TreeEvent {
105
108
  seq: number;
@@ -135,6 +138,8 @@ export interface TreeEventLogApi {
135
138
  }
136
139
  export type BoardRollupKey = CardState | 'unset';
137
140
  export interface Board {
141
+ /** phase C: the root's plan, ordered */
142
+ plan?: PlanView;
138
143
  rootId: string;
139
144
  /** tree event head at render time; pass back as `since` */
140
145
  cursor: number;
@@ -153,6 +158,8 @@ export interface BoardQuery {
153
158
  all?: boolean;
154
159
  }
155
160
  export interface BoardDeps {
161
+ /** phase C: archived session records */
162
+ listArchived?(): Promise<Session[]>;
156
163
  loadSession(id: string): Promise<Session | null>;
157
164
  listSessions(): Promise<Session[]>;
158
165
  attention(id: string): Promise<{
@@ -19,7 +19,7 @@ export const TREE_EVENTS_RETAIN = 5_000; // keep newest N on compaction
19
19
  export const TREE_EVENTS_COMPACT_AT = 6_000;
20
20
  export const TREE_EVENTS_MAX_WAIT_MS = 300_000;
21
21
  export const TREE_EVENT_SUMMARY_MAX = 300;
22
- export const TREE_EVENT_KINDS = ['status', 'attention', 'pr', 'preview', 'exit', 'idle', 'result', 'mail'];
22
+ export const TREE_EVENT_KINDS = ['status', 'attention', 'pr', 'preview', 'exit', 'idle', 'result', 'mail', 'plan', 'removed'];
23
23
  /**
24
24
  * Digest line format (exact):
25
25
  * `[ftown] since HH:MM: <part> | <part> | ...`
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/coordination/contract.ts"],"names":[],"mappings":"AASA,2FAA2F;AAE3F,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAG/F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAGpF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,GAAG;IACb,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,GAAG;IAChB,yDAAyD;IACzD,aAAa,EAAE,MAAM;CACb,CAAC;AA4BX,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,CAAC,CAAC;CACpF;AA8BD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC;AAoBzC,qEAAqE;AAErE,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,wBAAwB;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAG,8BAA8B;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAwEpH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B;;GAEG;AAEH,6EAA6E;AAE7E,iEAAiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAU,CAAC;AAEzF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAA4B,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,gGAAgG;AAChG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAsBnC,+GAA+G;AAE/G,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,8GAA8G;IAC9G,IAAI,EAAE,wBAAwB;IAC9B,2CAA2C;IAC3C,KAAK,EAAE,yBAAyB;IAChC,kFAAkF;IAClF,MAAM,EAAE,0BAA0B;CAC1B,CAAC;AAEX,iGAAiG;AACjG;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/coordination/contract.ts"],"names":[],"mappings":"AAUA,2FAA2F;AAE3F,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAG/F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAGpF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,GAAG;IACb,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,GAAG;IAChB,yDAAyD;IACzD,aAAa,EAAE,MAAM;CACb,CAAC;AA4BX,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,CAAC,CAAC;CACpF;AAgCD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC;AAoBzC,qEAAqE;AAErE,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,wBAAwB;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAG,8BAA8B;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AA4EvI;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B;;GAEG;AAEH,6EAA6E;AAE7E,iEAAiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAU,CAAC;AAEzF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAA4B,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,gGAAgG;AAChG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAsBnC,+GAA+G;AAE/G,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,8GAA8G;IAC9G,IAAI,EAAE,wBAAwB;IAC9B,2CAA2C;IAC3C,KAAK,EAAE,yBAAyB;IAChC,kFAAkF;IAClF,MAAM,EAAE,0BAA0B;CAC1B,CAAC;AAEX,iGAAiG;AACjG;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC"}
@@ -47,24 +47,50 @@ export function formatBoardRow(card, nowMs) {
47
47
  if (card.stale) {
48
48
  suffix += ' (stale)';
49
49
  }
50
+ if (card.archived) {
51
+ suffix += ' (retired)';
52
+ }
50
53
  return `${card.name} ${state} ${activity}${idlePart} ${headline}${suffix}`;
51
54
  }
55
+ const PLANNED_READY_LIMIT = 5;
56
+ function formatPlannedLines(board) {
57
+ const ready = board.plan?.ready ?? [];
58
+ if (ready.length === 0)
59
+ return [];
60
+ const titleById = new Map((board.plan?.items ?? []).map((item) => [item.id, item.title]));
61
+ const shown = ready.slice(0, PLANNED_READY_LIMIT);
62
+ const lines = ['planned'];
63
+ for (const id of shown) {
64
+ const title = titleById.get(id) ?? '';
65
+ lines.push(title === '' ? `→ ${id}` : `→ ${id} ${title}`);
66
+ }
67
+ const more = ready.length - shown.length;
68
+ if (more > 0)
69
+ lines.push(`+${more} more`);
70
+ return lines;
71
+ }
52
72
  export function formatBoard(board, nowMs) {
73
+ const lines = [];
53
74
  if (board.cards.length === 0) {
54
- return 'no child sessions';
75
+ lines.push('no child sessions');
55
76
  }
56
- const rows = board.cards.map((card) => formatBoardRow(card, nowMs));
57
- const rollupParts = [];
58
- for (const key of ROLLUP_ORDER) {
59
- const count = board.rollup[key] ?? 0;
60
- if (count > 0) {
61
- rollupParts.push(`${count} ${key}`);
77
+ else {
78
+ for (const card of board.cards) {
79
+ lines.push(formatBoardRow(card, nowMs));
80
+ }
81
+ const rollupParts = [];
82
+ for (const key of ROLLUP_ORDER) {
83
+ const count = board.rollup[key] ?? 0;
84
+ if (count > 0) {
85
+ rollupParts.push(`${count} ${key}`);
86
+ }
87
+ }
88
+ if (rollupParts.length > 0) {
89
+ lines.push(rollupParts.join(', '));
62
90
  }
63
91
  }
64
- if (rollupParts.length > 0) {
65
- rows.push(rollupParts.join(', '));
66
- }
67
- return rows.join('\n');
92
+ lines.push(...formatPlannedLines(board));
93
+ return lines.join('\n');
68
94
  }
69
95
  export function formatEvent(e) {
70
96
  const hhmm = formatLocalHHMM(e.ts);
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/coordination/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/coordination/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Plan list: precedence ordering, pure edits, and the session-backed store.
3
+ * Ordering follows PLAN_ORDER_RULE. Ids are `p<seq>` allocated from SessionPlan.seq
4
+ * and then incremented, so a removed id is never reused. A plan that does not exist
5
+ * yet starts at seq 1 (first item `p1`).
6
+ */
7
+ import type { Session } from '../types.js';
8
+ import { type PlanItem, type PlanPriority, type PlanState, type PlanView, type SessionPlan } from './contract-c.js';
9
+ export interface PlanAddInput {
10
+ title: string;
11
+ note?: string;
12
+ after?: string[];
13
+ priority?: PlanPriority;
14
+ }
15
+ export interface PlanPatchInput {
16
+ title?: string;
17
+ note?: string | null;
18
+ after?: string[];
19
+ priority?: PlanPriority;
20
+ state?: PlanState;
21
+ sessionId?: string | null;
22
+ }
23
+ export interface PlanStoreDeps {
24
+ loadSession(id: string): Promise<Session | null>;
25
+ saveSession(session: Session): Promise<void>;
26
+ publishSession(session: Session): void | Promise<void>;
27
+ emit(parent: Session, summary: string): Promise<void>;
28
+ now(): number;
29
+ }
30
+ /**
31
+ * Ready, then waiting, then started, then done, then dropped.
32
+ * Ready and waiting: priority ascending, then createdAt ascending.
33
+ * Started: updatedAt ascending. Done and dropped: updatedAt descending.
34
+ * Id number breaks remaining ties.
35
+ */
36
+ export declare function orderPlan(items: readonly PlanItem[]): PlanView;
37
+ /** Ids of todo items whose every `after` dependency is done or dropped, in plan order. */
38
+ export declare function readyIds(items: readonly PlanItem[]): string[];
39
+ /** Ids that are ready in `after` and were not ready in `before`, in the new ready order. */
40
+ export declare function newlyReady(before: readonly PlanItem[], after: readonly PlanItem[]): string[];
41
+ export declare function applyAdd(plan: SessionPlan | null | undefined, input: unknown, now: string): SessionPlan;
42
+ /** Validates a patch and returns the updated plan. `applyPatch` delegates here. */
43
+ export declare function validatePatch(plan: SessionPlan | null | undefined, input: unknown, now: string): SessionPlan;
44
+ export declare function applyPatch(plan: SessionPlan | null | undefined, input: unknown, now: string): SessionPlan;
45
+ export declare function applyRemove(plan: SessionPlan | null | undefined, input: unknown, now: string): SessionPlan;
46
+ /**
47
+ * Reloads the parent before every save. Each successful change publishes the saved
48
+ * session, then emits one `plan` summary — `<id> <state>: <title>`, plus
49
+ * ` → ready: <id>, <id>` when items became ready. An emit failure is warned and
50
+ * does not undo the publish.
51
+ */
52
+ export declare class PlanStore {
53
+ private readonly deps;
54
+ constructor(deps: PlanStoreDeps);
55
+ get(parentId: string): Promise<SessionPlan | null>;
56
+ add(parentId: string, input: PlanAddInput): Promise<PlanItem>;
57
+ patch(parentId: string, itemId: string, input: PlanPatchInput): Promise<PlanItem>;
58
+ remove(parentId: string, itemId: string): Promise<void>;
59
+ /** Binds a todo item to a child: state `started`, sessionId = childId. */
60
+ startForChild(parentId: string, itemId: string, childId: string): Promise<void>;
61
+ /**
62
+ * Marks every item with this child and state `started` as `done`.
63
+ * No match, or a missing parent, is a no-op: a failed card stays `started` for the manager.
64
+ */
65
+ completeForChild(parentId: string, childId: string): Promise<void>;
66
+ /**
67
+ * Returns every item with this child and state `started` to `todo` and clears sessionId.
68
+ * No match, or a missing parent, is a no-op. One event: `<id> todo: <title> (session removed)`.
69
+ */
70
+ releaseForChild(parentId: string, childId: string): Promise<void>;
71
+ private stamp;
72
+ private change;
73
+ private persist;
74
+ }