mainflow 0.36.0 → 0.38.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.
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { G as parseRef, K as parseUntil, N as UNTIL_FORMS, et as stampMs, n as CLOSED_STATUS, q as refExample } from "./dist-ud09dzZo.js";
3
- import { $ as nowMinute, B as applyOperation, C as readSession, H as HubError, Q as unavailableHubs, S as loadSessions, V as checkHubName, W as loadHub, Y as memberOfGroup, Z as remoteMembers, _ as initHub, _t as findHubRoot, at as MAX_FILE_BYTES, b as sessionBriefing, bt as DATA_DIR, d as retroReport, f as retroReportFromReceiver, ht as requireSlug, m as RETRY_RULES, mt as TASK_FILE, p as receiverFromEnv, pt as MAINLINE_FILE, tt as nodeStorage, u as migrateHub, v as untilState, xt as WriteError, y as duplicateClaimLines } from "./host-BauijAdm.js";
2
+ import { G as refExample, Q as stampMs, U as parseRef, W as parseUntil, j as UNTIL_FORMS, n as CLOSED_STATUS } from "./dist-CZYL5PJ4.js";
3
+ import { $ as nowMinute, B as applyOperation, C as readSession, Ct as WriteError, H as HubError, Q as unavailableHubs, S as loadSessions, St as DATA_DIR, V as checkHubName, W as loadHub, Y as memberOfGroup, Z as remoteMembers, _ as initHub, _t as requireSlug, at as MAX_FILE_BYTES, b as sessionBriefing, d as retroReport, f as retroReportFromReceiver, gt as TASK_FILE, ht as MAINLINE_FILE, m as RETRY_RULES, p as receiverFromEnv, tt as nodeStorage, u as migrateHub, v as untilState, y as duplicateClaimLines, yt as findHubRoot } from "./host-aYx3DYrv.js";
4
4
  import { t as listProgress } from "./progress-1BfPg2zN.js";
5
- import { C as ServerError, D as syncSettings, E as hubName, O as SETTINGS_FILE, S as ServerApi, T as earlierToken, _ as readDaemon, a as remoteMode, b as readRemote, c as planAnnounce, d as toolCallOf, f as startDaemon, g as probeDaemon, h as callDaemon, i as queuedCount, j as syncPaths, l as planFetch, m as DaemonUnavailable, n as hubWriter, o as fetchDenial, p as DaemonRunning, r as writtenLines, s as hookAnswer, t as CONFIRM_MS, u as planFlush, v as silentHint, w as ENV, x as oversizedFiles } from "./operation-DGRH4iBE.js";
5
+ import { C as ServerError, D as syncSettings, E as hubName, O as SETTINGS_FILE, S as ServerApi, T as earlierToken, _ as readDaemon, a as remoteMode, b as readRemote, c as planAnnounce, d as toolCallOf, f as startDaemon, g as probeDaemon, h as callDaemon, i as queuedCount, j as syncPaths, l as planFetch, m as DaemonUnavailable, n as hubWriter, o as fetchDenial, p as DaemonRunning, r as writtenLines, s as hookAnswer, t as CONFIRM_MS, u as planFlush, v as silentHint, w as ENV, x as oversizedFiles } from "./operation-1oQ8lA9C.js";
6
6
  import { COMMAND_SPECS, OPTIONS } from "./facts.js";
7
7
  import { hookFallback, parsePayload, runHook } from "./hooks.js";
8
- import { f as CLI_VERSION, i as launchUi, l as startUiInBackground, r as exitCodeFor, u as watchHubGone } from "./launch-n2ZDF0BF.js";
8
+ import { f as CLI_VERSION, i as launchUi, l as startUiInBackground, r as exitCodeFor, u as watchHubGone } from "./launch-D38sNgXM.js";
9
9
  import { randomBytes } from "node:crypto";
10
10
  import { existsSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
11
11
  import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -669,7 +669,6 @@ const WRITES = {
669
669
  slug: args[0],
670
670
  title: required(opts, "title", "--title \"重建 mainline 任務管理\""),
671
671
  group: opts.group,
672
- role: opts.role,
673
672
  priority: opts.priority
674
673
  }),
675
674
  print: (_, { id, dir }) => done(`created ${id} ${inData(dir, MAINLINE_FILE)}`)
@@ -754,14 +753,9 @@ const WRITES = {
754
753
  id: args[0],
755
754
  status: opts.status,
756
755
  group: opts.group,
757
- role: opts.role,
758
756
  priority: opts.priority
759
757
  }),
760
- print: (_, m) => done(`updated ${m.id} (${[
761
- m.status,
762
- m.group,
763
- m.role
764
- ].filter(Boolean).join(", ")})`)
758
+ print: (_, m) => done(`updated ${m.id} (${[m.status, m.group].filter(Boolean).join(", ")})`)
765
759
  }),
766
760
  "mainline archive": write({
767
761
  op: "mainline.archive",
@@ -1346,10 +1340,9 @@ function required(opts, name, example) {
1346
1340
  if (!value) throw new WriteError(`--${name} is required, e.g. ${example}`);
1347
1341
  return value;
1348
1342
  }
1349
- /** The group and role a mainline line ends with, like ` [w001, plan]`; nothing for an impl mainline outside a group. */
1343
+ /** The group a mainline line ends with, like ` [w001]`; nothing for a mainline outside a group. */
1350
1344
  const membership = (m) => {
1351
- const tags = [m.group, m.role === "plan" ? "plan" : void 0].filter(Boolean);
1352
- return tags.length ? ` [${tags.join(", ")}]` : "";
1345
+ return m.group ? ` [${m.group}]` : "";
1353
1346
  };
1354
1347
  function printStatus(hub, all) {
1355
1348
  const shown = hub.mainlines.filter((m) => all || !m.archivedAt);
@@ -1365,7 +1358,7 @@ function printStatus(hub, all) {
1365
1358
  }
1366
1359
  /**
1367
1360
  * Open groups by priority, P0 first and a group without one as P2, then by id; each with its trigger and its members:
1368
- * plan mainlines first, then impl mainlines, then issues. Archived and closed members are left out unless --all.
1361
+ * mainlines first, then issues. Archived and closed members are left out unless --all.
1369
1362
  */
1370
1363
  function printGroups(hub, all) {
1371
1364
  const rank = (p) => (p ?? "P2").slice(1);
@@ -1375,14 +1368,10 @@ function printGroups(hub, all) {
1375
1368
  console.log(` ${g.id} ${g.status.padEnd(4)} ${g.priority ?? "P2"} ${g.title}${g.trigger ? ` (時機:${g.trigger})` : ""}`);
1376
1369
  const mainlines = hub.mainlines.filter((m) => memberOfGroup(m.group, g.id, hub.config.hub) && (all || !m.archivedAt && !CLOSED_STATUS.mainline.includes(m.status)));
1377
1370
  const issues = hub.issues.filter((i) => memberOfGroup(i.group, g.id, hub.config.hub) && (all || !i.archivedAt && i.status !== "closed"));
1378
- for (const m of [...mainlines.filter((m) => m.role === "plan"), ...mainlines.filter((m) => m.role !== "plan")]) console.log(` ${m.id} ${(m.role ?? "impl").padEnd(4)} ${m.status.padEnd(8)} ${m.title}`);
1379
- for (const i of issues) console.log(` ${i.id} issue ${i.status.padEnd(8)} ${i.title}`);
1371
+ for (const m of mainlines) console.log(` ${m.id} mainline ${m.status.padEnd(8)} ${m.title}`);
1372
+ for (const i of issues) console.log(` ${i.id} issue ${i.status.padEnd(8)} ${i.title}`);
1380
1373
  const remote = (remoteByGroup.get(g.id) ?? []).filter((m) => all || !m.archived && m.open);
1381
- for (const m of [
1382
- ...remote.filter((m) => m.role === "plan"),
1383
- ...remote.filter((m) => m.kind === "mainline" && m.role !== "plan"),
1384
- ...remote.filter((m) => m.kind === "issue")
1385
- ]) console.log(` ${m.ref} ${(m.kind === "issue" ? "issue" : m.role).padEnd(4)} ${m.status.padEnd(8)} ${m.title}`);
1374
+ for (const m of [...remote.filter((m) => m.kind === "mainline"), ...remote.filter((m) => m.kind === "issue")]) console.log(` ${m.ref} ${(m.kind === "issue" ? "issue" : "mainline").padEnd(8)} ${m.status.padEnd(8)} ${m.title}`);
1386
1375
  }
1387
1376
  const missing = unavailableHubs(hub.remotes);
1388
1377
  if (missing.length) console.log(` note: hub ${missing.join(", ")} not loaded, so their members are not listed`);
@@ -765,13 +765,6 @@ const grantSchema = z.object({
765
765
  message: parsed.message
766
766
  });
767
767
  });
768
- /**
769
- * What a mainline is for. A plan mainline sizes the work, splits it into impl mainlines, coordinates them and makes
770
- * the final check; an impl mainline carries a piece of the work out. A mainline without a role is an impl one, and
771
- * a group may hold no plan mainline at all: a small piece of work needs none.
772
- */
773
- const MAINLINE_ROLES = ["plan", "impl"];
774
- const DEFAULT_ROLE = "impl";
775
768
  const mainlineSchema = z.object({
776
769
  id: id("mainline"),
777
770
  title: text,
@@ -779,7 +772,6 @@ const mainlineSchema = z.object({
779
772
  priority,
780
773
  ...documentShape,
781
774
  group,
782
- role: z.enum(MAINLINE_ROLES).optional(),
783
775
  due: date.optional(),
784
776
  /** Hidden from the default listings; independent of status, a done mainline may stay visible */
785
777
  archivedAt: date.optional(),
@@ -1051,8 +1043,8 @@ const findingSchema = z.object({
1051
1043
  archivedAt: date.optional()
1052
1044
  });
1053
1045
  /**
1054
- * Front matter of groups/w{NNN}-{slug}.md: mainlines and issues that belong together, such as a plan mainline with the
1055
- * impl mainlines it split off, or the issues to take up together when a measurement is fixed. Membership is written
1046
+ * Front matter of groups/w{NNN}-{slug}.md: mainlines and issues that belong together, such as the mainlines that split one
1047
+ * piece of work, or the issues to take up together when a measurement is fixed. Membership is written
1056
1048
  * on each member (`group`), so a group file never lists its members and the two cannot disagree. A group is apart
1057
1049
  * from dependencies: depends-on between groups orders them, and priority and trigger say how urgent and when.
1058
1050
  */
@@ -1095,4 +1087,4 @@ function parseOpsLine(line) {
1095
1087
  return parsed.success ? parsed.data : null;
1096
1088
  }
1097
1089
  //#endregion
1098
- export { OFFSET as $, SURVEY_SECTION as A, issueSchema as B, REF_EXAMPLES as C, SESSION_STATUS as D, SESSION_ID as E, configSchema as F, parseRef as G, opsEntrySchema as H, decisionSchema as I, refMainline as J, parseUntil as K, findingSchema as L, TASK_SECTIONS as M, UNTIL_FORMS as N, SLUG as O, WORK_STATUS as P, waitingForRef as Q, formatOpsEntry as R, PRIORITIES as S, SERVES_REF as T, parseActionRef as U, mainlineSchema as V, parseOpsLine as W, taskSchema as X, sessionSchema as Y, waitingForAction as Z, LINK_RELS as _, DECISION_SECTIONS as a, grantCovers as at, MAINLINE_STATUS as b, DEFAULT_ROLE as c, parseGrantTarget as ct, FORMAT_VERSION as d, stampMs as et, GROUP_SECTIONS as f, ISSUE_STATUS as g, ISSUE_SECTIONS as h, DECISION_BASES as i, describeRequest as it, TASK_REQUIRED_SECTIONS as j, SURVEY_LINES as k, FINDING_SECTIONS as l, ID_PATTERNS as m, CLOSED_STATUS as n, GRANT_FORMS as nt, DECISION_STATUS as o, grantForm as ot, GROUP_STATUS as p, refExample as q, DECIDERS as r, GRANT_TARGET_FORMS as rt, DEFAULT_CATEGORIES as s, grantRepo as st, CHECKLIST_REF as t, GRANT_ACTIONS as tt, FINDING_STATUS as u, MAINLINE_ROLES as v, RESERVED_HUB_NAMES as w, MERGE_STATES as x, MAINLINE_SECTIONS as y, groupSchema as z };
1090
+ export { GRANT_ACTIONS as $, TASK_SECTIONS as A, opsEntrySchema as B, SERVES_REF as C, SURVEY_LINES as D, SLUG as E, findingSchema as F, refExample as G, parseOpsLine as H, formatOpsEntry as I, taskSchema as J, refMainline as K, groupSchema as L, WORK_STATUS as M, configSchema as N, SURVEY_SECTION as O, decisionSchema as P, stampMs as Q, issueSchema as R, RESERVED_HUB_NAMES as S, SESSION_STATUS as T, parseRef as U, parseActionRef as V, parseUntil as W, waitingForRef as X, waitingForAction as Y, OFFSET as Z, MAINLINE_SECTIONS as _, DECISION_SECTIONS as a, grantRepo as at, PRIORITIES as b, FINDING_SECTIONS as c, GROUP_SECTIONS as d, GRANT_FORMS as et, GROUP_STATUS as f, LINK_RELS as g, ISSUE_STATUS as h, DECISION_BASES as i, grantForm as it, UNTIL_FORMS as j, TASK_REQUIRED_SECTIONS as k, FINDING_STATUS as l, ISSUE_SECTIONS as m, CLOSED_STATUS as n, describeRequest as nt, DECISION_STATUS as o, parseGrantTarget as ot, ID_PATTERNS as p, sessionSchema as q, DECIDERS as r, grantCovers as rt, DEFAULT_CATEGORIES as s, CHECKLIST_REF as t, GRANT_TARGET_FORMS as tt, FORMAT_VERSION as u, MAINLINE_STATUS as v, SESSION_ID as w, REF_EXAMPLES as x, MERGE_STATES as y, mainlineSchema as z };
package/dist/facts.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { g as SurveyLine, l as ID_PATTERNS, m as SLUG, o as FORMAT_VERSION, p as SERVES_REF, r as CHECKLIST_REF, v as Until } from "./index-B32s8PHu.js";
1
+ import { g as SurveyLine, l as ID_PATTERNS, m as SLUG, o as FORMAT_VERSION, p as SERVES_REF, r as CHECKLIST_REF, v as Until } from "./index-BH9gpiap.js";
2
2
  //#region src/facts.d.ts
3
3
  export interface CommandSpec {
4
4
  usage: string;
@@ -124,8 +124,8 @@ export declare const COMMAND_SPECS: {
124
124
  readonly needsHub: false;
125
125
  };
126
126
  readonly 'new mainline': {
127
- readonly usage: 'new mainline <slug> --title <title> [--group <w>] [--role plan|impl] [--priority P0|P1|P2|P3]';
128
- readonly summary: 'Create mainline.md with the next id and the section template; write the rest in the file. --group puts it in an existing group, or in one of another registered hub as {hub}:w001; --role plan makes it the mainline that splits the work, coordinates it and makes the final check (without --role it is an impl mainline)';
127
+ readonly usage: 'new mainline <slug> --title <title> [--group <w>] [--priority P0|P1|P2|P3]';
128
+ readonly summary: 'Create mainline.md with the next id and the section template; write the rest in the file. --group puts it in an existing group, or in one of another registered hub as {hub}:w001';
129
129
  readonly args: 1;
130
130
  readonly needsHub: true;
131
131
  };
@@ -167,13 +167,13 @@ export declare const COMMAND_SPECS: {
167
167
  };
168
168
  readonly 'group list': {
169
169
  readonly usage: 'group list [--all]';
170
- readonly summary: 'List open groups by priority with their trigger and members, plan mainlines first; members in other hubs read {hub}:{id}, and a registered hub that is not loaded is noted (--all includes done groups)';
170
+ readonly summary: 'List open groups by priority with their trigger and members, mainlines before issues; members in other hubs read {hub}:{id}, and a registered hub that is not loaded is noted (--all includes done groups)';
171
171
  readonly args: 0;
172
172
  readonly needsHub: true;
173
173
  };
174
174
  readonly 'mainline set': {
175
- readonly usage: 'mainline set <m> [--status <status>] [--group <w|none>] [--role plan|impl] [--priority P0|P1|P2|P3]';
176
- readonly summary: 'Change status, group, role or priority; done needs every criterion met and no proposed decision. A planning mainline becomes active by itself when work on it starts, so use --status for paused, done and dropped. --group none leaves the group; {hub}:w001 joins a group of another registered hub';
175
+ readonly usage: 'mainline set <m> [--status <status>] [--group <w|none>] [--priority P0|P1|P2|P3]';
176
+ readonly summary: 'Change status, group or priority; done needs every criterion met and no proposed decision. A planning mainline becomes active by itself when work on it starts, so use --status for paused, done and dropped. --group none leaves the group; {hub}:w001 joins a group of another registered hub';
177
177
  readonly args: 1;
178
178
  readonly needsHub: true;
179
179
  };
@@ -495,9 +495,6 @@ export declare const OPTIONS: {
495
495
  readonly group: {
496
496
  readonly type: 'string';
497
497
  };
498
- readonly role: {
499
- readonly type: 'string';
500
- };
501
498
  readonly priority: {
502
499
  readonly type: 'string';
503
500
  };
@@ -676,15 +673,6 @@ export declare const CLASSIFICATION: {
676
673
  readonly priorities: readonly ["P0", "P1", "P2", "P3"];
677
674
  readonly defaultPriority: "P2";
678
675
  };
679
- /**
680
- * What a mainline is for: a plan mainline sizes the work, splits it into impl mainlines, coordinates them and makes
681
- * the final check; an impl mainline carries a piece out. Without a role a mainline is `default`. A group needs no plan
682
- * mainline: whether to open one, and how many impl mainlines, follows from how big the work is.
683
- */
684
- export declare const ROLES: {
685
- readonly values: readonly ["plan", "impl"];
686
- readonly default: "impl";
687
- };
688
676
  /** Body sections each document is created with; the task sections in `taskRequired` must be filled while it is open. */
689
677
  export declare const SECTIONS: {
690
678
  readonly mainline: readonly ["概述", "背景與前置", "現況查核", "範圍與不做", "限制"];
@@ -712,7 +700,7 @@ export interface FieldSpec {
712
700
  }
713
701
  /** Every front matter field of each document and list entry; facts.test keeps it equal to the schema. */
714
702
  export declare const FIELDS: {
715
- readonly mainline: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
703
+ readonly mainline: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
716
704
  readonly task: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
717
705
  readonly decision: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
718
706
  readonly issue: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
package/dist/facts.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as SURVEY_SECTION, D as SESSION_STATUS, M as TASK_SECTIONS, N as UNTIL_FORMS, O as SLUG, P as WORK_STATUS, S as PRIORITIES, T as SERVES_REF, _ as LINK_RELS, a as DECISION_SECTIONS, b as MAINLINE_STATUS, c as DEFAULT_ROLE, d as FORMAT_VERSION, f as GROUP_SECTIONS, g as ISSUE_STATUS, h as ISSUE_SECTIONS, i as DECISION_BASES, j as TASK_REQUIRED_SECTIONS, k as SURVEY_LINES, l as FINDING_SECTIONS, m as ID_PATTERNS, n as CLOSED_STATUS, nt as GRANT_FORMS, o as DECISION_STATUS, p as GROUP_STATUS, r as DECIDERS, rt as GRANT_TARGET_FORMS, s as DEFAULT_CATEGORIES, t as CHECKLIST_REF, tt as GRANT_ACTIONS, u as FINDING_STATUS, v as MAINLINE_ROLES, x as MERGE_STATES, y as MAINLINE_SECTIONS } from "./dist-ud09dzZo.js";
1
+ import { $ as GRANT_ACTIONS, A as TASK_SECTIONS, C as SERVES_REF, D as SURVEY_LINES, E as SLUG, M as WORK_STATUS, O as SURVEY_SECTION, T as SESSION_STATUS, _ as MAINLINE_SECTIONS, a as DECISION_SECTIONS, b as PRIORITIES, c as FINDING_SECTIONS, d as GROUP_SECTIONS, et as GRANT_FORMS, f as GROUP_STATUS, g as LINK_RELS, h as ISSUE_STATUS, i as DECISION_BASES, j as UNTIL_FORMS, k as TASK_REQUIRED_SECTIONS, l as FINDING_STATUS, m as ISSUE_SECTIONS, n as CLOSED_STATUS, o as DECISION_STATUS, p as ID_PATTERNS, r as DECIDERS, s as DEFAULT_CATEGORIES, t as CHECKLIST_REF, tt as GRANT_TARGET_FORMS, u as FORMAT_VERSION, v as MAINLINE_STATUS, y as MERGE_STATES } from "./dist-CZYL5PJ4.js";
2
2
  import { a as LABEL_ROLES, i as FINDING_SEVERITIES, n as FINDING_CLASSES, r as FINDING_FIELDS, t as FINDINGS_FENCE } from "./retro-formats-ECy0gGOL.js";
3
3
  //#region src/facts.ts
4
4
  const COMMAND_SPECS = {
@@ -114,8 +114,8 @@ const COMMAND_SPECS = {
114
114
  needsHub: false
115
115
  },
116
116
  "new mainline": {
117
- usage: "new mainline <slug> --title <title> [--group <w>] [--role plan|impl] [--priority P0|P1|P2|P3]",
118
- summary: "Create mainline.md with the next id and the section template; write the rest in the file. --group puts it in an existing group, or in one of another registered hub as {hub}:w001; --role plan makes it the mainline that splits the work, coordinates it and makes the final check (without --role it is an impl mainline)",
117
+ usage: "new mainline <slug> --title <title> [--group <w>] [--priority P0|P1|P2|P3]",
118
+ summary: "Create mainline.md with the next id and the section template; write the rest in the file. --group puts it in an existing group, or in one of another registered hub as {hub}:w001",
119
119
  args: 1,
120
120
  needsHub: true
121
121
  },
@@ -157,13 +157,13 @@ const COMMAND_SPECS = {
157
157
  },
158
158
  "group list": {
159
159
  usage: "group list [--all]",
160
- summary: "List open groups by priority with their trigger and members, plan mainlines first; members in other hubs read {hub}:{id}, and a registered hub that is not loaded is noted (--all includes done groups)",
160
+ summary: "List open groups by priority with their trigger and members, mainlines before issues; members in other hubs read {hub}:{id}, and a registered hub that is not loaded is noted (--all includes done groups)",
161
161
  args: 0,
162
162
  needsHub: true
163
163
  },
164
164
  "mainline set": {
165
- usage: "mainline set <m> [--status <status>] [--group <w|none>] [--role plan|impl] [--priority P0|P1|P2|P3]",
166
- summary: "Change status, group, role or priority; done needs every criterion met and no proposed decision. A planning mainline becomes active by itself when work on it starts, so use --status for paused, done and dropped. --group none leaves the group; {hub}:w001 joins a group of another registered hub",
165
+ usage: "mainline set <m> [--status <status>] [--group <w|none>] [--priority P0|P1|P2|P3]",
166
+ summary: "Change status, group or priority; done needs every criterion met and no proposed decision. A planning mainline becomes active by itself when work on it starts, so use --status for paused, done and dropped. --group none leaves the group; {hub}:w001 joins a group of another registered hub",
167
167
  args: 1,
168
168
  needsHub: true
169
169
  },
@@ -418,7 +418,6 @@ const OPTIONS = {
418
418
  origin: { type: "string" },
419
419
  labels: { type: "string" },
420
420
  group: { type: "string" },
421
- role: { type: "string" },
422
421
  priority: { type: "string" },
423
422
  trigger: { type: "string" },
424
423
  target: { type: "string" },
@@ -575,15 +574,6 @@ const CLASSIFICATION = {
575
574
  priorities: PRIORITIES,
576
575
  defaultPriority: "P2"
577
576
  };
578
- /**
579
- * What a mainline is for: a plan mainline sizes the work, splits it into impl mainlines, coordinates them and makes
580
- * the final check; an impl mainline carries a piece out. Without a role a mainline is `default`. A group needs no plan
581
- * mainline: whether to open one, and how many impl mainlines, follows from how big the work is.
582
- */
583
- const ROLES = {
584
- values: MAINLINE_ROLES,
585
- default: DEFAULT_ROLE
586
- };
587
577
  /** Body sections each document is created with; the task sections in `taskRequired` must be filled while it is open. */
588
578
  const SECTIONS = {
589
579
  mainline: MAINLINE_SECTIONS,
@@ -655,7 +645,6 @@ const FIELDS = {
655
645
  mainline: [
656
646
  ...shared(...EVERY),
657
647
  field("group", false, "所屬的組 w{NNN},或其他 hub 的組 {hub}:w{NNN},一條主脈絡最多一組;組和依賴無關"),
658
- field("role", false, "plan 是拆分顆粒、整合調度與最終確認的規劃型,impl 是執行的實作型;沒填視為 impl"),
659
648
  field("due", false, "預計完成的日期"),
660
649
  field("archivedAt", false, "封存的日期,和狀態分開"),
661
650
  field("criteria", true, "解決條件清單,每條的欄位見 criterion"),
@@ -728,4 +717,4 @@ const FIELDS = {
728
717
  ]
729
718
  };
730
719
  //#endregion
731
- export { CHECKLIST_REF, CLASSIFICATION, CLOSED_STATUSES, COMMAND_SPECS, FIELDS, FORMAT_VERSION, GRANTS, ID_PATTERNS, LAYOUT, LINKS, OPTIONS, REFERENCES, RETRO_FORMATS, ROLES, SECTIONS, SERVES_REF, SLUG, STATUSES, SURVEY, UNTIL };
720
+ export { CHECKLIST_REF, CLASSIFICATION, CLOSED_STATUSES, COMMAND_SPECS, FIELDS, FORMAT_VERSION, GRANTS, ID_PATTERNS, LAYOUT, LINKS, OPTIONS, REFERENCES, RETRO_FORMATS, SECTIONS, SERVES_REF, SLUG, STATUSES, SURVEY, UNTIL };
@@ -1,4 +1,4 @@
1
- import "./index-B32s8PHu.js";
1
+ import "./index-BH9gpiap.js";
2
2
  //#region ../schema/dist/grants.d.ts
3
3
  /** An operation about to run, resolved to what a grant is written against. */
4
4
  type GrantRequest = {
@@ -1,4 +1,4 @@
1
- import { nt as GRANT_FORMS } from "./dist-ud09dzZo.js";
1
+ import { et as GRANT_FORMS } from "./dist-CZYL5PJ4.js";
2
2
  import { closeSync, constants, fstatSync, openSync, readFileSync, realpathSync } from "node:fs";
3
3
  import { isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { spawnSync } from "node:child_process";
package/dist/hooks.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as Task, a as Decision, c as Group, d as Mainline, f as OpsEntry, h as Session, i as ChecklistItem, n as ActionBlock, s as Finding, t as Action, u as Issue } from "./index-B32s8PHu.js";
1
+ import { _ as Task, a as Decision, c as Group, d as Mainline, f as OpsEntry, h as Session, i as ChecklistItem, n as ActionBlock, s as Finding, t as Action, u as Issue } from "./index-BH9gpiap.js";
2
2
  import { z } from "zod";
3
3
  //#region ../core/dist/ids/allocators.d.ts
4
4
  /** The letters ids start with. */
@@ -123,8 +123,6 @@ interface MainlineInput {
123
123
  title: string;
124
124
  /** A group of this hub the mainline belongs to */
125
125
  group?: string;
126
- /** plan or impl; without one the mainline is an impl one */
127
- role?: string;
128
126
  priority?: string;
129
127
  }
130
128
  declare function createMainline(hub: HubReader, input: MainlineInput, ctx: OpContext): OpResult<{
@@ -137,12 +135,11 @@ interface MainlinePatch {
137
135
  status?: string;
138
136
  /** A group of this hub, or `none` (null) to leave every group */
139
137
  group?: string | null;
140
- role?: string;
141
138
  priority?: string;
142
139
  expectedVersion?: string;
143
140
  }
144
141
  /**
145
- * Change a mainline's status, group, role or priority. Done is refused while criteria are open or decisions are
142
+ * Change a mainline's status, group or priority. Done is refused while criteria are open or decisions are
146
143
  * proposed; the other fields change without conditions, in the same write.
147
144
  */
148
145
  declare function setMainline(hub: HubReader, input: MainlinePatch, ctx: OpContext): OpResult<Mainline>;
package/dist/hooks.js CHANGED
@@ -1,6 +1,6 @@
1
- import { F as configSchema, it as describeRequest } from "./dist-ud09dzZo.js";
2
- import { A as mayDecorate, C as readSession, D as decorateReply, E as matchGrants, H as HubError, O as endsWithMarker, S as loadSessions, T as grantScope, W as loadHub, _t as findHubRoot, b as sessionBriefing, bt as DATA_DIR, et as readYaml, gt as currentBranch, i as hostName, k as headerLine, vt as worktreesOf, x as turnReminder } from "./host-BauijAdm.js";
3
- import { n as hubWriter, r as writtenLines } from "./operation-DGRH4iBE.js";
1
+ import { N as configSchema, nt as describeRequest } from "./dist-CZYL5PJ4.js";
2
+ import { A as mayDecorate, C as readSession, D as decorateReply, E as matchGrants, H as HubError, O as endsWithMarker, S as loadSessions, St as DATA_DIR, T as grantScope, W as loadHub, b as sessionBriefing, bt as worktreesOf, et as readYaml, i as hostName, k as headerLine, mt as hubFormatVersion, pt as formatMismatch, tt as nodeStorage, vt as currentBranch, x as turnReminder, yt as findHubRoot } from "./host-aYx3DYrv.js";
3
+ import { n as hubWriter, r as writtenLines } from "./operation-1oQ8lA9C.js";
4
4
  import { resolveFixed, scanCommand, scopedCwd } from "./grant-commands.js";
5
5
  import { appendFileSync, existsSync, readFileSync } from "node:fs";
6
6
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
@@ -425,6 +425,18 @@ const PROJECT_HUB_EVENTS = /* @__PURE__ */ new Set(["pre-tool-use"]);
425
425
  function hubRootFor(event, ctx) {
426
426
  return (PROJECT_HUB_EVENTS.has(event) && ctx.projectDir && isAbsolute(ctx.projectDir) ? findHubRoot(ctx.projectDir) : null) ?? findHubRoot(typeof ctx.payload.cwd === "string" ? ctx.payload.cwd : process.cwd());
427
427
  }
428
+ /** Events whose output reaches the model before it works, so they carry the notice that the hub's data format does not match this CLI. */
429
+ const FORMAT_NOTICE_EVENTS = /* @__PURE__ */ new Set(["session-start", "user-prompt-submit"]);
430
+ /** What the model is told when the hub's data format is not the one this CLI reads and writes; null when it is. */
431
+ function formatNotice(root, cli) {
432
+ const found = hubFormatVersion(nodeStorage(root));
433
+ const reason = found === null ? null : formatMismatch(found);
434
+ if (found === null || reason === null) return null;
435
+ return {
436
+ text: found < 3 ? `[mainflow] 這個 hub 的資料格式是 ${found},這版 mainflow 讀寫的是 3,要先跑 ${cli} migrate 才能讀寫紀錄。` : `[mainflow] 這個 hub 的資料格式是 ${found},比這版 mainflow 讀寫的 3 新,要先在這個 hub 安裝對應版本的 mainflow 才能讀寫紀錄。`,
437
+ reason
438
+ };
439
+ }
428
440
  /** What an event prints when it cannot run its handler; null for the events that stay silent. */
429
441
  function hookFallback(platform, event, ctx, failure) {
430
442
  const fallback = HOOK_FALLBACKS[platform]?.[event];
@@ -461,6 +473,11 @@ async function runHook(platform, event, ctx) {
461
473
  for (const line of writtenLines(written)) if (line.startsWith("!")) warn(`mainflow hook ${platform} ${event}: ${line.slice(2)}`);
462
474
  return written;
463
475
  };
476
+ const notice = FORMAT_NOTICE_EVENTS.has(event) ? formatNotice(root, ctx.cli) : null;
477
+ if (notice) return {
478
+ stdout: notice.text,
479
+ error: errorText(`mainflow hook ${platform} ${event}: ${notice.reason}`)
480
+ };
464
481
  return {
465
482
  stdout: await handler(root, {
466
483
  ...ctx,