mainflow 0.34.0 → 0.35.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 +81 -9
- package/dist/{dist-IdbnCDqM.js → dist-BdvWGTsb.js} +47 -4
- package/dist/facts.d.ts +67 -13
- package/dist/facts.js +63 -14
- package/dist/grant-commands.d.ts +1 -1
- package/dist/grant-commands.js +1 -1
- package/dist/hooks.d.ts +63 -9
- package/dist/hooks.js +3 -3
- package/dist/{host-79T-_NMu.js → host-bnHYIwuY.js} +476 -199
- package/dist/host.d.ts +9 -0
- package/dist/host.js +2 -2
- package/dist/{index-ihgXABQc.d.ts → index-DgYB5u1f.d.ts} +52 -1
- package/dist/launch-D80CYPcm.js +327 -0
- package/dist/launch.d.ts +50 -4
- package/dist/launch.js +2 -2
- package/dist/native/mainflow-swap-darwin-arm64 +0 -0
- package/dist/native/mainflow-swap-darwin-x64 +0 -0
- package/dist/{operation--fJnUqvA.js → operation-DVcJgKM9.js} +2 -2
- package/dist/{ui-BcXPk-0P.js → ui-C4h4iLDu.js} +132 -12
- package/dist/web/assets/index-BDnlbKcr.js +82 -0
- package/dist/web/assets/index-Z6UfQ6pW.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/launch-DQVyIbpf.js +0 -205
- package/dist/web/assets/index-CC7l6bNN.css +0 -1
- package/dist/web/assets/index-CDNCPMjD.js +0 -82
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { G as parseRef, K as parseUntil, N as UNTIL_FORMS, et as stampMs, n as CLOSED_STATUS, q as refExample } from "./dist-BdvWGTsb.js";
|
|
3
|
+
import { B as applyOperation, C as readSession, H as HubError, Q as nodeStorage, S as loadSessions, V as checkHubName, W as loadHub, X as nowMinute, _ as initHub, _t as DATA_DIR, b as sessionBriefing, d as retroReport, dt as TASK_FILE, f as retroReportFromReceiver, ft as requireSlug, m as RETRY_RULES, mt as findHubRoot, nt as MAX_FILE_BYTES, p as receiverFromEnv, u as migrateHub, ut as MAINLINE_FILE, v as untilState, vt as WriteError, y as duplicateClaimLines } from "./host-bnHYIwuY.js";
|
|
4
4
|
import { t as listProgress } from "./progress-1BfPg2zN.js";
|
|
5
|
-
import {
|
|
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-DVcJgKM9.js";
|
|
6
6
|
import { COMMAND_SPECS, OPTIONS } from "./facts.js";
|
|
7
7
|
import { hookFallback, parsePayload, runHook } from "./hooks.js";
|
|
8
|
-
import {
|
|
8
|
+
import { f as CLI_VERSION, i as launchUi, l as startUiInBackground, r as exitCodeFor, u as watchHubGone } from "./launch-D80CYPcm.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";
|
|
@@ -654,7 +654,10 @@ const WRITES = {
|
|
|
654
654
|
op: "mainline.new",
|
|
655
655
|
input: ({ args, opts }) => ({
|
|
656
656
|
slug: args[0],
|
|
657
|
-
title: required(opts, "title", "--title \"重建 mainline 任務管理\"")
|
|
657
|
+
title: required(opts, "title", "--title \"重建 mainline 任務管理\""),
|
|
658
|
+
group: opts.group,
|
|
659
|
+
role: opts.role,
|
|
660
|
+
priority: opts.priority
|
|
658
661
|
}),
|
|
659
662
|
print: (_, { id, dir }) => done(`created ${id} ${inData(dir, MAINLINE_FILE)}`)
|
|
660
663
|
}),
|
|
@@ -689,10 +692,37 @@ const WRITES = {
|
|
|
689
692
|
slug: args[0],
|
|
690
693
|
title: required(opts, "title", "--title \"重試不穩定的 VM\""),
|
|
691
694
|
origin: opts.origin,
|
|
695
|
+
labels: opts.labels ? list(opts.labels) : void 0,
|
|
696
|
+
group: opts.group,
|
|
697
|
+
priority: opts.priority
|
|
698
|
+
}),
|
|
699
|
+
print: (_, { id, file }) => done(`created ${id} ${inData(file)}`)
|
|
700
|
+
}),
|
|
701
|
+
"new group": write({
|
|
702
|
+
op: "group.new",
|
|
703
|
+
input: ({ args, opts }) => ({
|
|
704
|
+
slug: args[0],
|
|
705
|
+
title: required(opts, "title", "--title \"量測修正\""),
|
|
706
|
+
priority: opts.priority,
|
|
707
|
+
trigger: opts.trigger,
|
|
708
|
+
origin: opts.origin,
|
|
692
709
|
labels: opts.labels ? list(opts.labels) : void 0
|
|
693
710
|
}),
|
|
694
711
|
print: (_, { id, file }) => done(`created ${id} ${inData(file)}`)
|
|
695
712
|
}),
|
|
713
|
+
"group set": write({
|
|
714
|
+
op: "group.set",
|
|
715
|
+
input: ({ args, opts }) => ({
|
|
716
|
+
id: args[0],
|
|
717
|
+
patch: {
|
|
718
|
+
status: opts.status,
|
|
719
|
+
priority: opts.priority,
|
|
720
|
+
trigger: opts.trigger,
|
|
721
|
+
title: opts.title
|
|
722
|
+
}
|
|
723
|
+
}),
|
|
724
|
+
print: (_, g) => done(`updated ${g.id} (${g.status})`)
|
|
725
|
+
}),
|
|
696
726
|
"new finding": write({
|
|
697
727
|
op: "finding.new",
|
|
698
728
|
input: ({ args, opts }) => ({
|
|
@@ -707,9 +737,16 @@ const WRITES = {
|
|
|
707
737
|
op: "mainline.set",
|
|
708
738
|
input: ({ args, opts }) => ({
|
|
709
739
|
id: args[0],
|
|
710
|
-
status:
|
|
740
|
+
status: opts.status,
|
|
741
|
+
group: opts.group,
|
|
742
|
+
role: opts.role,
|
|
743
|
+
priority: opts.priority
|
|
711
744
|
}),
|
|
712
|
-
print: (_, m) => done(`updated ${m.id} (${
|
|
745
|
+
print: (_, m) => done(`updated ${m.id} (${[
|
|
746
|
+
m.status,
|
|
747
|
+
m.group,
|
|
748
|
+
m.role
|
|
749
|
+
].filter(Boolean).join(", ")})`)
|
|
713
750
|
}),
|
|
714
751
|
"mainline archive": write({
|
|
715
752
|
op: "mainline.archive",
|
|
@@ -853,6 +890,17 @@ const WRITES = {
|
|
|
853
890
|
}),
|
|
854
891
|
print: (_, i) => done(`closed ${i.id}`)
|
|
855
892
|
}),
|
|
893
|
+
"issue set": write({
|
|
894
|
+
op: "issue.set",
|
|
895
|
+
input: ({ args, opts }) => ({
|
|
896
|
+
id: args[0],
|
|
897
|
+
patch: {
|
|
898
|
+
group: opts.group,
|
|
899
|
+
priority: opts.priority
|
|
900
|
+
}
|
|
901
|
+
}),
|
|
902
|
+
print: (_, i) => done(`updated ${i.id}${i.group ? ` (${i.group})` : ""}`)
|
|
903
|
+
}),
|
|
856
904
|
"issue reopen": write({
|
|
857
905
|
op: "issue.reopen",
|
|
858
906
|
input: ({ args }) => ({ id: args[0] }),
|
|
@@ -980,6 +1028,8 @@ const RUNS = {
|
|
|
980
1028
|
launchUi(root, config.hub, config.ui?.port, {
|
|
981
1029
|
port: opts.port,
|
|
982
1030
|
open: !opts["no-open"]
|
|
1031
|
+
}).then((result) => {
|
|
1032
|
+
process.exitCode = exitCodeFor(result);
|
|
983
1033
|
}).catch((error) => {
|
|
984
1034
|
console.error(error instanceof WriteError ? `✗ ${error.message}` : error);
|
|
985
1035
|
process.exitCode = 1;
|
|
@@ -1034,9 +1084,10 @@ const RUNS = {
|
|
|
1034
1084
|
},
|
|
1035
1085
|
"issue list": ({ root, opts }) => {
|
|
1036
1086
|
const shown = loadHub(root).issues.filter((i) => opts.all || i.status !== "closed");
|
|
1037
|
-
for (const i of shown) console.log(` ${i.id} ${i.status.padEnd(7)} ${i.title}${i.plannedIn ? ` → ${i.plannedIn}` : ""}${i.origin ? ` (from ${i.origin})` : ""}`);
|
|
1087
|
+
for (const i of shown) console.log(` ${i.id} ${i.status.padEnd(7)} ${i.title}${i.plannedIn ? ` → ${i.plannedIn}` : ""}${i.origin ? ` (from ${i.origin})` : ""}${i.group ? ` [${i.group}]` : ""}`);
|
|
1038
1088
|
return done(`${shown.length} issues`);
|
|
1039
1089
|
},
|
|
1090
|
+
"group list": ({ root, opts }) => printGroups(loadHub(root), opts.all ?? false),
|
|
1040
1091
|
"finding list": ({ root, opts }) => {
|
|
1041
1092
|
const shown = loadHub(root).findings.filter((f) => opts.all || f.status === "valid");
|
|
1042
1093
|
for (const f of shown) console.log(` ${f.id} ${f.created} ${f.title}${f.labels?.length ? ` [${f.labels.join(", ")}]` : ""}`);
|
|
@@ -1279,18 +1330,39 @@ function required(opts, name, example) {
|
|
|
1279
1330
|
if (!value) throw new WriteError(`--${name} is required, e.g. ${example}`);
|
|
1280
1331
|
return value;
|
|
1281
1332
|
}
|
|
1333
|
+
/** The group and role a mainline line ends with, like ` [w001, plan]`; nothing for an impl mainline outside a group. */
|
|
1334
|
+
const membership = (m) => {
|
|
1335
|
+
const tags = [m.group, m.role === "plan" ? "plan" : void 0].filter(Boolean);
|
|
1336
|
+
return tags.length ? ` [${tags.join(", ")}]` : "";
|
|
1337
|
+
};
|
|
1282
1338
|
function printStatus(hub, all) {
|
|
1283
1339
|
const shown = hub.mainlines.filter((m) => all || !m.archivedAt);
|
|
1284
1340
|
console.log(`${hub.config.hub}: ${shown.length} mainlines${all ? "" : " (archived hidden)"}`);
|
|
1285
1341
|
for (const m of shown) {
|
|
1286
1342
|
const items = listProgress(m.tasks.flatMap((t) => t.checklist));
|
|
1287
1343
|
const archived = m.archivedAt ? " [archived]" : "";
|
|
1288
|
-
console.log(` ${m.id} ${m.status.padEnd(8)} ${items.done}/${items.total} ${m.title}${archived}`);
|
|
1344
|
+
console.log(` ${m.id} ${m.status.padEnd(8)} ${items.done}/${items.total} ${m.title}${membership(m)}${archived}`);
|
|
1289
1345
|
}
|
|
1290
1346
|
if (hub.problems.length === 0) return 0;
|
|
1291
1347
|
console.error(`${hub.problems.length} problems found; run "mainflow check" for details`);
|
|
1292
1348
|
return 1;
|
|
1293
1349
|
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Open groups by priority, P0 first and a group without one as P2, then by id; each with its trigger and its members:
|
|
1352
|
+
* plan mainlines first, then impl mainlines, then issues. Archived and closed members are left out unless --all.
|
|
1353
|
+
*/
|
|
1354
|
+
function printGroups(hub, all) {
|
|
1355
|
+
const rank = (p) => (p ?? "P2").slice(1);
|
|
1356
|
+
const shown = hub.groups.filter((g) => all || g.status !== "done").sort((a, b) => rank(a.priority).localeCompare(rank(b.priority)) || a.id.localeCompare(b.id));
|
|
1357
|
+
for (const g of shown) {
|
|
1358
|
+
console.log(` ${g.id} ${g.status.padEnd(4)} ${g.priority ?? "P2"} ${g.title}${g.trigger ? ` (時機:${g.trigger})` : ""}`);
|
|
1359
|
+
const mainlines = hub.mainlines.filter((m) => m.group === g.id && (all || !m.archivedAt && !CLOSED_STATUS.mainline.includes(m.status)));
|
|
1360
|
+
const issues = hub.issues.filter((i) => i.group === g.id && (all || !i.archivedAt && i.status !== "closed"));
|
|
1361
|
+
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}`);
|
|
1362
|
+
for (const i of issues) console.log(` ${i.id} issue ${i.status.padEnd(8)} ${i.title}`);
|
|
1363
|
+
}
|
|
1364
|
+
return done(`${shown.length} groups`);
|
|
1365
|
+
}
|
|
1294
1366
|
function printProblems(problems, mark = "✗") {
|
|
1295
1367
|
for (const problem of problems) console.error(`${mark} ${problem.file}${problem.field ? ` › ${problem.field}` : ""}: ${problem.message}`);
|
|
1296
1368
|
}
|
|
@@ -376,6 +376,8 @@ const ID_PATTERNS = {
|
|
|
376
376
|
action: /^a\d{3}$/,
|
|
377
377
|
issue: /^i\d{3}$/,
|
|
378
378
|
finding: /^f\d{3}$/,
|
|
379
|
+
/** A hub-level group of mainlines and issues; groups/w{NNN}-{slug}.md */
|
|
380
|
+
group: /^w\d{3}$/,
|
|
379
381
|
grant: /^g\d{3}$/
|
|
380
382
|
};
|
|
381
383
|
const CHECKLIST_REF = /^m\d{3}\/t\d{3}#c\d{3}$/;
|
|
@@ -422,6 +424,11 @@ const REF_FORMS = [
|
|
|
422
424
|
kind: "finding",
|
|
423
425
|
pattern: /^(f\d{3})$/,
|
|
424
426
|
example: "f001"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
kind: "group",
|
|
430
|
+
pattern: /^(w\d{3})$/,
|
|
431
|
+
example: "w001"
|
|
425
432
|
}
|
|
426
433
|
];
|
|
427
434
|
/** The forms a reference can take, for error messages. */
|
|
@@ -488,13 +495,17 @@ function parseLocal(input) {
|
|
|
488
495
|
kind: "finding",
|
|
489
496
|
finding: a
|
|
490
497
|
};
|
|
498
|
+
case "group": return {
|
|
499
|
+
kind: "group",
|
|
500
|
+
group: a
|
|
501
|
+
};
|
|
491
502
|
}
|
|
492
503
|
}
|
|
493
504
|
return null;
|
|
494
505
|
}
|
|
495
506
|
/** The reference a blocked task waits for, when its whole `waitingFor` text is one; free text such as 使用者 gives undefined. */
|
|
496
507
|
const waitingForRef = (waitingFor) => waitingFor && parseRef(waitingFor) ? waitingFor : void 0;
|
|
497
|
-
/** The mainline a reference sits in, or undefined for hub-level issues and
|
|
508
|
+
/** The mainline a reference sits in, or undefined for hub-level issues, findings and groups. */
|
|
498
509
|
const refMainline = (ref) => "mainline" in ref ? ref.mainline : void 0;
|
|
499
510
|
/** The example reference for a kind, used in error messages. */
|
|
500
511
|
const refExample = (kind) => REF_FORMS.find((f) => f.kind === kind)?.example ?? "";
|
|
@@ -549,13 +560,16 @@ const SESSION_STATUS = [
|
|
|
549
560
|
"ended",
|
|
550
561
|
"handed-off"
|
|
551
562
|
];
|
|
563
|
+
/** A group is open while any of the work it gathers is still to be done, and done once it is all settled. */
|
|
564
|
+
const GROUP_STATUS = ["open", "done"];
|
|
552
565
|
/** Statuses after which an entity is closed and carries closedAt. */
|
|
553
566
|
const CLOSED_STATUS = {
|
|
554
567
|
mainline: ["done", "dropped"],
|
|
555
568
|
task: ["done", "dropped"],
|
|
556
569
|
decision: ["superseded"],
|
|
557
570
|
issue: ["closed"],
|
|
558
|
-
finding: ["obsolete"]
|
|
571
|
+
finding: ["obsolete"],
|
|
572
|
+
group: ["done"]
|
|
559
573
|
};
|
|
560
574
|
/** Default categories, aligned with Conventional Commits types; a hub adds its own in config.yaml. */
|
|
561
575
|
const DEFAULT_CATEGORIES = [
|
|
@@ -609,6 +623,8 @@ const FINDING_SECTIONS = [
|
|
|
609
623
|
"影響",
|
|
610
624
|
"做法"
|
|
611
625
|
];
|
|
626
|
+
/** 說明 says what the group gathers and why; its first paragraph is the summary the interface shows on the group's heading. */
|
|
627
|
+
const GROUP_SECTIONS = ["說明"];
|
|
612
628
|
const SURVEY_SECTION = "現況查核";
|
|
613
629
|
const SURVEY_LINES = [
|
|
614
630
|
{
|
|
@@ -666,7 +682,7 @@ const linkSchema = z.object({
|
|
|
666
682
|
note: text.optional()
|
|
667
683
|
});
|
|
668
684
|
/**
|
|
669
|
-
* Attributes every document carries (mainline, task, decision, issue, finding) besides id, title, status
|
|
685
|
+
* Attributes every document carries (mainline, task, decision, issue, finding, group) besides id, title, status
|
|
670
686
|
* and priority, which each schema lists first so the front matter reads the same way in every file. `category` is checked
|
|
671
687
|
* against DEFAULT_CATEGORIES plus config.categories when the hub loads, not here, because the schema does
|
|
672
688
|
* not see the config. `updated` is not stored: readers derive it from the file.
|
|
@@ -683,6 +699,8 @@ const documentShape = {
|
|
|
683
699
|
links: z.array(linkSchema).optional()
|
|
684
700
|
};
|
|
685
701
|
const priority = z.enum(PRIORITIES).optional();
|
|
702
|
+
/** The hub-level group a mainline or an issue belongs to, at most one; work that goes together, apart from what depends on what */
|
|
703
|
+
const group = id("group").optional();
|
|
686
704
|
const evidenceRequired = (item, ctx) => {
|
|
687
705
|
if (item.done && !item.evidence) ctx.addIssue({
|
|
688
706
|
code: "custom",
|
|
@@ -744,12 +762,21 @@ const grantSchema = z.object({
|
|
|
744
762
|
message: parsed.message
|
|
745
763
|
});
|
|
746
764
|
});
|
|
765
|
+
/**
|
|
766
|
+
* What a mainline is for. A plan mainline sizes the work, splits it into impl mainlines, coordinates them and makes
|
|
767
|
+
* the final check; an impl mainline carries a piece of the work out. A mainline without a role is an impl one, and
|
|
768
|
+
* a group may hold no plan mainline at all: a small piece of work needs none.
|
|
769
|
+
*/
|
|
770
|
+
const MAINLINE_ROLES = ["plan", "impl"];
|
|
771
|
+
const DEFAULT_ROLE = "impl";
|
|
747
772
|
const mainlineSchema = z.object({
|
|
748
773
|
id: id("mainline"),
|
|
749
774
|
title: text,
|
|
750
775
|
status: z.enum(MAINLINE_STATUS),
|
|
751
776
|
priority,
|
|
752
777
|
...documentShape,
|
|
778
|
+
group,
|
|
779
|
+
role: z.enum(MAINLINE_ROLES).optional(),
|
|
753
780
|
due: date.optional(),
|
|
754
781
|
/** Hidden from the default listings; independent of status, a done mainline may stay visible */
|
|
755
782
|
archivedAt: date.optional(),
|
|
@@ -980,6 +1007,7 @@ const issueSchema = z.object({
|
|
|
980
1007
|
status: z.enum(ISSUE_STATUS),
|
|
981
1008
|
priority,
|
|
982
1009
|
...documentShape,
|
|
1010
|
+
group,
|
|
983
1011
|
order: z.number().int().positive().optional(),
|
|
984
1012
|
due: date.optional(),
|
|
985
1013
|
plannedIn: z.string().regex(/^m\d{3}\/t\d{3}$/).optional(),
|
|
@@ -1010,6 +1038,21 @@ const findingSchema = z.object({
|
|
|
1010
1038
|
/** Hidden from the default views; independent of status, an obsolete finding stays visible until archived */
|
|
1011
1039
|
archivedAt: date.optional()
|
|
1012
1040
|
});
|
|
1041
|
+
/**
|
|
1042
|
+
* Front matter of groups/w{NNN}-{slug}.md: mainlines and issues that belong together, such as a plan mainline with the
|
|
1043
|
+
* impl mainlines it split off, or the issues to take up together when a measurement is fixed. Membership is written
|
|
1044
|
+
* on each member (`group`), so a group file never lists its members and the two cannot disagree. A group is apart
|
|
1045
|
+
* from dependencies: depends-on between groups orders them, and priority and trigger say how urgent and when.
|
|
1046
|
+
*/
|
|
1047
|
+
const groupSchema = z.object({
|
|
1048
|
+
id: id("group"),
|
|
1049
|
+
title: text,
|
|
1050
|
+
status: z.enum(GROUP_STATUS),
|
|
1051
|
+
priority,
|
|
1052
|
+
...documentShape,
|
|
1053
|
+
/** When to take the group's work up, in a phrase, e.g. 量測修正時 */
|
|
1054
|
+
trigger: text.optional()
|
|
1055
|
+
});
|
|
1013
1056
|
/** One line of ops/{YYYY-MM}.log: an external operation, append-only. */
|
|
1014
1057
|
const opsEntrySchema = z.object({
|
|
1015
1058
|
at: datetime,
|
|
@@ -1040,4 +1083,4 @@ function parseOpsLine(line) {
|
|
|
1040
1083
|
return parsed.success ? parsed.data : null;
|
|
1041
1084
|
}
|
|
1042
1085
|
//#endregion
|
|
1043
|
-
export {
|
|
1086
|
+
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 };
|
package/dist/facts.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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-DgYB5u1f.js";
|
|
2
2
|
//#region src/facts.d.ts
|
|
3
3
|
export interface CommandSpec {
|
|
4
4
|
usage: string;
|
|
@@ -106,7 +106,7 @@ export declare const COMMAND_SPECS: {
|
|
|
106
106
|
};
|
|
107
107
|
readonly 'action set': {
|
|
108
108
|
readonly usage: 'action set <a|session#a> [--status] [--reason --waiting-for --until] [--text] [--serves] [--before <a>] [--note <text>] [--session <session>]';
|
|
109
|
-
readonly summary: 'Change, reorder or finish an action; --status blocked needs --reason, and leaving blocked clears it. --status doing reminds like action add. A handed-off action keeps its note';
|
|
109
|
+
readonly summary: 'Change, reorder or finish an action; --status blocked needs --reason, and leaving blocked clears it. --status doing reminds like action add and moves a planning mainline it serves to active. A handed-off action keeps its note';
|
|
110
110
|
readonly args: 1;
|
|
111
111
|
readonly needsHub: true;
|
|
112
112
|
};
|
|
@@ -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>';
|
|
128
|
-
readonly summary: 'Create mainline.md with the next id and the section template; write the rest in the file';
|
|
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; --role plan makes it the mainline that splits the work, coordinates it and makes the final check (without --role it is an impl mainline)';
|
|
129
129
|
readonly args: 1;
|
|
130
130
|
readonly needsHub: true;
|
|
131
131
|
};
|
|
@@ -142,8 +142,8 @@ export declare const COMMAND_SPECS: {
|
|
|
142
142
|
readonly needsHub: true;
|
|
143
143
|
};
|
|
144
144
|
readonly 'new issue': {
|
|
145
|
-
readonly usage: 'new issue <slug> --title <title> [--origin <ref>] [--labels a,b]';
|
|
146
|
-
readonly summary: 'Create an issue file for a follow-up that must outlive its mainline';
|
|
145
|
+
readonly usage: 'new issue <slug> --title <title> [--origin <ref>] [--labels a,b] [--group <w>] [--priority P0|P1|P2|P3]';
|
|
146
|
+
readonly summary: 'Create an issue file for a follow-up that must outlive its mainline; --group puts it with the work it is taken up with';
|
|
147
147
|
readonly args: 1;
|
|
148
148
|
readonly needsHub: true;
|
|
149
149
|
};
|
|
@@ -153,9 +153,27 @@ export declare const COMMAND_SPECS: {
|
|
|
153
153
|
readonly args: 1;
|
|
154
154
|
readonly needsHub: true;
|
|
155
155
|
};
|
|
156
|
+
readonly 'new group': {
|
|
157
|
+
readonly usage: 'new group <slug> --title <title> [--priority P0|P1|P2|P3] [--trigger <when>] [--origin <ref>] [--labels a,b]';
|
|
158
|
+
readonly summary: 'Create a group file for mainlines and issues taken up together, apart from dependencies; --trigger says when, e.g. "量測修正時". Members join with --group on new mainline, new issue, mainline set or issue set';
|
|
159
|
+
readonly args: 1;
|
|
160
|
+
readonly needsHub: true;
|
|
161
|
+
};
|
|
162
|
+
readonly 'group set': {
|
|
163
|
+
readonly usage: 'group set <w> [--status open|done] [--priority P0|P1|P2|P3] [--trigger <when>] [--title <title>]';
|
|
164
|
+
readonly summary: 'Change a group\'s status, priority, trigger or title; an empty --trigger "" removes it. Relations between groups go in links in the file';
|
|
165
|
+
readonly args: 1;
|
|
166
|
+
readonly needsHub: true;
|
|
167
|
+
};
|
|
168
|
+
readonly 'group list': {
|
|
169
|
+
readonly usage: 'group list [--all]';
|
|
170
|
+
readonly summary: 'List open groups by priority with their trigger and members, plan mainlines first (--all includes done groups)';
|
|
171
|
+
readonly args: 0;
|
|
172
|
+
readonly needsHub: true;
|
|
173
|
+
};
|
|
156
174
|
readonly 'mainline set': {
|
|
157
|
-
readonly usage: 'mainline set <m> --status <status>';
|
|
158
|
-
readonly summary: 'Change status; done needs every criterion met and no proposed decision';
|
|
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';
|
|
159
177
|
readonly args: 1;
|
|
160
178
|
readonly needsHub: true;
|
|
161
179
|
};
|
|
@@ -197,7 +215,7 @@ export declare const COMMAND_SPECS: {
|
|
|
197
215
|
};
|
|
198
216
|
readonly 'task set': {
|
|
199
217
|
readonly usage: 'task set <m/t> [--status] [--reason --waiting-for --signal] [--repo] [--branch --worktree --base --merge]';
|
|
200
|
-
readonly summary: 'Change status, repository or branch state; --status blocked needs --reason';
|
|
218
|
+
readonly summary: 'Change status, repository or branch state; --status blocked needs --reason. --status doing also moves a planning mainline to active';
|
|
201
219
|
readonly args: 1;
|
|
202
220
|
readonly needsHub: true;
|
|
203
221
|
};
|
|
@@ -215,7 +233,7 @@ export declare const COMMAND_SPECS: {
|
|
|
215
233
|
};
|
|
216
234
|
readonly 'item check': {
|
|
217
235
|
readonly usage: 'item check <m/t#c> --evidence <evidence>';
|
|
218
|
-
readonly summary: 'Check an item with evidence';
|
|
236
|
+
readonly summary: 'Check an item with evidence; also moves a planning mainline to active';
|
|
219
237
|
readonly args: 1;
|
|
220
238
|
readonly needsHub: true;
|
|
221
239
|
};
|
|
@@ -273,6 +291,12 @@ export declare const COMMAND_SPECS: {
|
|
|
273
291
|
readonly args: 1;
|
|
274
292
|
readonly needsHub: true;
|
|
275
293
|
};
|
|
294
|
+
readonly 'issue set': {
|
|
295
|
+
readonly usage: 'issue set <i> [--group <w|none>] [--priority P0|P1|P2|P3]';
|
|
296
|
+
readonly summary: 'Put an issue in a group, or take it out with --group none, and change its priority';
|
|
297
|
+
readonly args: 1;
|
|
298
|
+
readonly needsHub: true;
|
|
299
|
+
};
|
|
276
300
|
readonly 'issue list': {
|
|
277
301
|
readonly usage: 'issue list [--all]';
|
|
278
302
|
readonly summary: 'List open and planned issues (--all includes closed)';
|
|
@@ -316,7 +340,7 @@ export declare const COMMAND_SPECS: {
|
|
|
316
340
|
readonly needsHub: true;
|
|
317
341
|
};
|
|
318
342
|
readonly 'section append': {
|
|
319
|
-
readonly usage: 'section append <m|m/t|m/d|i|f> <heading> <text>';
|
|
343
|
+
readonly usage: 'section append <m|m/t|m/d|i|f|w> <heading> <text>';
|
|
320
344
|
readonly summary: 'Add text at the end of a section of a document\'s body, such as a line under a task\'s 紀錄; two appends keep both, in order. The text is taken as written, even when it starts with "-"; a list line follows the list directly, other text comes after a blank line';
|
|
321
345
|
readonly args: 3;
|
|
322
346
|
readonly literalLast: true;
|
|
@@ -468,6 +492,18 @@ export declare const OPTIONS: {
|
|
|
468
492
|
readonly labels: {
|
|
469
493
|
readonly type: 'string';
|
|
470
494
|
};
|
|
495
|
+
readonly group: {
|
|
496
|
+
readonly type: 'string';
|
|
497
|
+
};
|
|
498
|
+
readonly role: {
|
|
499
|
+
readonly type: 'string';
|
|
500
|
+
};
|
|
501
|
+
readonly priority: {
|
|
502
|
+
readonly type: 'string';
|
|
503
|
+
};
|
|
504
|
+
readonly trigger: {
|
|
505
|
+
readonly type: 'string';
|
|
506
|
+
};
|
|
471
507
|
readonly target: {
|
|
472
508
|
readonly type: 'string';
|
|
473
509
|
};
|
|
@@ -515,6 +551,7 @@ export declare const STATUSES: {
|
|
|
515
551
|
readonly decision: readonly ["proposed", "accepted", "superseded"];
|
|
516
552
|
readonly issue: readonly ["open", "planned", "closed"];
|
|
517
553
|
readonly finding: readonly ["valid", "obsolete"];
|
|
554
|
+
readonly group: readonly ["open", "done"];
|
|
518
555
|
readonly session: readonly ["active", "paused", "ended", "handed-off"];
|
|
519
556
|
readonly merge: readonly ["open", "merged", "abandoned"];
|
|
520
557
|
readonly decider: readonly ["user", "ai", "relay"];
|
|
@@ -549,6 +586,10 @@ export declare const REFERENCES: readonly [{
|
|
|
549
586
|
readonly target: 'finding';
|
|
550
587
|
readonly format: 'f{NNN}';
|
|
551
588
|
readonly example: 'f001';
|
|
589
|
+
}, {
|
|
590
|
+
readonly target: 'group';
|
|
591
|
+
readonly format: 'w{NNN}';
|
|
592
|
+
readonly example: 'w001';
|
|
552
593
|
}, {
|
|
553
594
|
readonly target: 'another hub';
|
|
554
595
|
readonly format: '{hub}:{reference}';
|
|
@@ -616,6 +657,7 @@ export declare const LAYOUT: {
|
|
|
616
657
|
readonly task: '.mainflow/mainlines/m{NNN}-{slug}/tasks/t{NNN}-{slug}/task.md';
|
|
617
658
|
readonly issue: '.mainflow/issues/i{NNN}-{slug}.md';
|
|
618
659
|
readonly finding: '.mainflow/findings/f{NNN}-{slug}.md';
|
|
660
|
+
readonly group: '.mainflow/groups/w{NNN}-{slug}.md';
|
|
619
661
|
readonly ops: '.mainflow/ops/{YYYY-MM}.log';
|
|
620
662
|
readonly sessions: '.mainflow/local/sessions/{sessionId}.yaml';
|
|
621
663
|
};
|
|
@@ -626,6 +668,7 @@ export declare const CLOSED_STATUSES: {
|
|
|
626
668
|
readonly decision: readonly ['superseded'];
|
|
627
669
|
readonly issue: readonly ['closed'];
|
|
628
670
|
readonly finding: readonly ['obsolete'];
|
|
671
|
+
readonly group: readonly ['done'];
|
|
629
672
|
};
|
|
630
673
|
/** Classification every document shares: one category from the list (a hub adds more in config.yaml), P0 to P3. */
|
|
631
674
|
export declare const CLASSIFICATION: {
|
|
@@ -633,6 +676,15 @@ export declare const CLASSIFICATION: {
|
|
|
633
676
|
readonly priorities: readonly ["P0", "P1", "P2", "P3"];
|
|
634
677
|
readonly defaultPriority: "P2";
|
|
635
678
|
};
|
|
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
|
+
};
|
|
636
688
|
/** Body sections each document is created with; the task sections in `taskRequired` must be filled while it is open. */
|
|
637
689
|
export declare const SECTIONS: {
|
|
638
690
|
readonly mainline: readonly ["概述", "背景與前置", "現況查核", "範圍與不做", "限制"];
|
|
@@ -641,6 +693,7 @@ export declare const SECTIONS: {
|
|
|
641
693
|
readonly decision: readonly ["背景", "選項", "建議", "決定", "理由"];
|
|
642
694
|
readonly issue: readonly ["背景", "要做的事", "完成條件"];
|
|
643
695
|
readonly finding: readonly ["發現", "影響", "做法"];
|
|
696
|
+
readonly group: readonly ["說明"];
|
|
644
697
|
};
|
|
645
698
|
/**
|
|
646
699
|
* The mainline section that records what was checked before tasks were written, one `- {label}:{text}`
|
|
@@ -659,11 +712,12 @@ export interface FieldSpec {
|
|
|
659
712
|
}
|
|
660
713
|
/** Every front matter field of each document and list entry; facts.test keeps it equal to the schema. */
|
|
661
714
|
export declare const FIELDS: {
|
|
662
|
-
readonly mainline: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
715
|
+
readonly mainline: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
663
716
|
readonly task: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
664
717
|
readonly decision: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
665
|
-
readonly issue: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
718
|
+
readonly issue: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|
|
666
719
|
readonly finding: readonly [...FieldSpec[], FieldSpec, FieldSpec, FieldSpec];
|
|
720
|
+
readonly group: readonly [...FieldSpec[], FieldSpec];
|
|
667
721
|
readonly criterion: FieldSpec[];
|
|
668
722
|
readonly checklistItem: readonly [...FieldSpec[], FieldSpec];
|
|
669
723
|
readonly grant: readonly [FieldSpec, FieldSpec, FieldSpec, FieldSpec];
|