mainflow 0.35.0-beta.1 → 0.36.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 +31 -6
- package/dist/{dist-BdvWGTsb.js → dist-ud09dzZo.js} +14 -2
- package/dist/facts.d.ts +7 -7
- package/dist/facts.js +9 -9
- package/dist/grant-commands.d.ts +1 -1
- package/dist/grant-commands.js +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +3 -3
- package/dist/{host-bnHYIwuY.js → host-BauijAdm.js} +181 -18
- package/dist/host.js +1 -1
- package/dist/{index-DgYB5u1f.d.ts → index-B32s8PHu.d.ts} +5 -1
- package/dist/{launch-D80CYPcm.js → launch-n2ZDF0BF.js} +2 -2
- package/dist/launch.js +1 -1
- package/dist/native/mainflow-swap-darwin-arm64 +0 -0
- package/dist/native/mainflow-swap-darwin-x64 +0 -0
- package/dist/{operation-DVcJgKM9.js → operation-DGRH4iBE.js} +1 -1
- package/dist/{ui-C4h4iLDu.js → ui-C-laSyqU.js} +13 -6
- package/dist/web/assets/{index-BDnlbKcr.js → index-8SRwJNYs.js} +4 -4
- package/dist/web/assets/index-CuHEjqof.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-Z6UfQ6pW.css +0 -1
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-
|
|
3
|
-
import { B as applyOperation, C as readSession, H as HubError, Q as
|
|
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";
|
|
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-
|
|
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";
|
|
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-
|
|
8
|
+
import { f as CLI_VERSION, i as launchUi, l as startUiInBackground, r as exitCodeFor, u as watchHubGone } from "./launch-n2ZDF0BF.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";
|
|
@@ -524,6 +524,18 @@ function retroText(report) {
|
|
|
524
524
|
//#endregion
|
|
525
525
|
//#region src/cli.ts
|
|
526
526
|
const write = (spec) => spec;
|
|
527
|
+
/**
|
|
528
|
+
* A group of another hub (`other-hub:w001`) must exist there when that hub is on this machine; the operation only
|
|
529
|
+
* checks that the hub is registered, since a hub kept on another machine cannot be read from here.
|
|
530
|
+
*/
|
|
531
|
+
const checkGroupOption = ({ root, opts }) => {
|
|
532
|
+
const ref = opts.group ? parseRef(opts.group) : null;
|
|
533
|
+
if (ref?.kind !== "group" || ref.hub === void 0) return;
|
|
534
|
+
const hub = loadHub(root);
|
|
535
|
+
if (ref.hub === hub.config.hub) return;
|
|
536
|
+
const remote = hub.remotes.find((r) => r.name === ref.hub);
|
|
537
|
+
if (remote?.hub && !remote.hub.groups.some((g) => g.id === ref.group)) throw new WriteError(`group ${ref.group} not found in hub "${ref.hub}"`);
|
|
538
|
+
};
|
|
527
539
|
/** Where a document an operation created or changed is, as the commands print it: .mainflow/... */
|
|
528
540
|
const inData = (...parts) => join(DATA_DIR, ...parts);
|
|
529
541
|
const WRITES = {
|
|
@@ -651,6 +663,7 @@ const WRITES = {
|
|
|
651
663
|
}
|
|
652
664
|
}),
|
|
653
665
|
"new mainline": write({
|
|
666
|
+
check: checkGroupOption,
|
|
654
667
|
op: "mainline.new",
|
|
655
668
|
input: ({ args, opts }) => ({
|
|
656
669
|
slug: args[0],
|
|
@@ -687,6 +700,7 @@ const WRITES = {
|
|
|
687
700
|
print: (_, { ref, file }) => done(`created ${ref} ${inData(file)}`)
|
|
688
701
|
}),
|
|
689
702
|
"new issue": write({
|
|
703
|
+
check: checkGroupOption,
|
|
690
704
|
op: "issue.new",
|
|
691
705
|
input: ({ args, opts }) => ({
|
|
692
706
|
slug: args[0],
|
|
@@ -734,6 +748,7 @@ const WRITES = {
|
|
|
734
748
|
print: (_, { id, file }) => done(`created ${id} ${inData(file)}`)
|
|
735
749
|
}),
|
|
736
750
|
"mainline set": write({
|
|
751
|
+
check: checkGroupOption,
|
|
737
752
|
op: "mainline.set",
|
|
738
753
|
input: ({ args, opts }) => ({
|
|
739
754
|
id: args[0],
|
|
@@ -891,6 +906,7 @@ const WRITES = {
|
|
|
891
906
|
print: (_, i) => done(`closed ${i.id}`)
|
|
892
907
|
}),
|
|
893
908
|
"issue set": write({
|
|
909
|
+
check: checkGroupOption,
|
|
894
910
|
op: "issue.set",
|
|
895
911
|
input: ({ args, opts }) => ({
|
|
896
912
|
id: args[0],
|
|
@@ -1353,14 +1369,23 @@ function printStatus(hub, all) {
|
|
|
1353
1369
|
*/
|
|
1354
1370
|
function printGroups(hub, all) {
|
|
1355
1371
|
const rank = (p) => (p ?? "P2").slice(1);
|
|
1372
|
+
const remoteByGroup = remoteMembers(hub.remotes, hub.config.hub);
|
|
1356
1373
|
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
1374
|
for (const g of shown) {
|
|
1358
1375
|
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
|
|
1360
|
-
const issues = hub.issues.filter((i) => i.group
|
|
1376
|
+
const mainlines = hub.mainlines.filter((m) => memberOfGroup(m.group, g.id, hub.config.hub) && (all || !m.archivedAt && !CLOSED_STATUS.mainline.includes(m.status)));
|
|
1377
|
+
const issues = hub.issues.filter((i) => memberOfGroup(i.group, g.id, hub.config.hub) && (all || !i.archivedAt && i.status !== "closed"));
|
|
1361
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}`);
|
|
1362
1379
|
for (const i of issues) console.log(` ${i.id} issue ${i.status.padEnd(8)} ${i.title}`);
|
|
1380
|
+
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}`);
|
|
1363
1386
|
}
|
|
1387
|
+
const missing = unavailableHubs(hub.remotes);
|
|
1388
|
+
if (missing.length) console.log(` note: hub ${missing.join(", ")} not loaded, so their members are not listed`);
|
|
1364
1389
|
return done(`${shown.length} groups`);
|
|
1365
1390
|
}
|
|
1366
1391
|
function printProblems(problems, mark = "✗") {
|
|
@@ -699,8 +699,11 @@ const documentShape = {
|
|
|
699
699
|
links: z.array(linkSchema).optional()
|
|
700
700
|
};
|
|
701
701
|
const priority = z.enum(PRIORITIES).optional();
|
|
702
|
-
/**
|
|
703
|
-
|
|
702
|
+
/**
|
|
703
|
+
* The hub-level group a mainline or an issue belongs to, at most one; work that goes together, apart from what depends on what.
|
|
704
|
+
* It is a group of this hub (`w001`) or of another one (`other-hub:w001`), so work in one hub can join a group of another.
|
|
705
|
+
*/
|
|
706
|
+
const group = z.string().refine((s) => parseRef(s)?.kind === "group", `expected a group like ${refExample("group")}, or one of another hub's like other-hub:${refExample("group")}`).optional();
|
|
704
707
|
const evidenceRequired = (item, ctx) => {
|
|
705
708
|
if (item.done && !item.evidence) ctx.addIssue({
|
|
706
709
|
code: "custom",
|
|
@@ -889,6 +892,11 @@ const UNTIL_FORMS = [
|
|
|
889
892
|
kind: "file",
|
|
890
893
|
format: "file:{relative path}",
|
|
891
894
|
example: "file:packages/cli/dist/cli.js"
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
kind: "mainline-done",
|
|
898
|
+
format: "mainline-done:m{NNN} or mainline-done:{hub}:m{NNN}",
|
|
899
|
+
example: "mainline-done:other-hub:m031"
|
|
892
900
|
}
|
|
893
901
|
];
|
|
894
902
|
const UNTIL_EXAMPLES = UNTIL_FORMS.map((f) => f.format).join(", ");
|
|
@@ -922,6 +930,10 @@ function parseUntil(input) {
|
|
|
922
930
|
kind,
|
|
923
931
|
path: argument
|
|
924
932
|
} : null;
|
|
933
|
+
case "mainline-done": return parseRef(argument)?.kind === "mainline" ? {
|
|
934
|
+
kind,
|
|
935
|
+
mainline: argument
|
|
936
|
+
} : null;
|
|
925
937
|
default: return null;
|
|
926
938
|
}
|
|
927
939
|
}
|
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-
|
|
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";
|
|
2
2
|
//#region src/facts.d.ts
|
|
3
3
|
export interface CommandSpec {
|
|
4
4
|
usage: string;
|
|
@@ -125,7 +125,7 @@ export declare const COMMAND_SPECS: {
|
|
|
125
125
|
};
|
|
126
126
|
readonly 'new mainline': {
|
|
127
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)';
|
|
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)';
|
|
129
129
|
readonly args: 1;
|
|
130
130
|
readonly needsHub: true;
|
|
131
131
|
};
|
|
@@ -143,7 +143,7 @@ export declare const COMMAND_SPECS: {
|
|
|
143
143
|
};
|
|
144
144
|
readonly 'new issue': {
|
|
145
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';
|
|
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, in this hub or another registered one ({hub}:w001)';
|
|
147
147
|
readonly args: 1;
|
|
148
148
|
readonly needsHub: true;
|
|
149
149
|
};
|
|
@@ -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 (--all includes done groups)';
|
|
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)';
|
|
171
171
|
readonly args: 0;
|
|
172
172
|
readonly needsHub: true;
|
|
173
173
|
};
|
|
174
174
|
readonly 'mainline set': {
|
|
175
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';
|
|
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';
|
|
177
177
|
readonly args: 1;
|
|
178
178
|
readonly needsHub: true;
|
|
179
179
|
};
|
|
@@ -293,7 +293,7 @@ export declare const COMMAND_SPECS: {
|
|
|
293
293
|
};
|
|
294
294
|
readonly 'issue set': {
|
|
295
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';
|
|
296
|
+
readonly summary: 'Put an issue in a group (of this hub, or {hub}:w001 of another registered one), or take it out with --group none, and change its priority';
|
|
297
297
|
readonly args: 1;
|
|
298
298
|
readonly needsHub: true;
|
|
299
299
|
};
|
|
@@ -620,7 +620,7 @@ export declare const RETRO_FORMATS: {
|
|
|
620
620
|
};
|
|
621
621
|
/**
|
|
622
622
|
* Conditions a blocked action's `until` takes and `wait` checks, one example each: a commit on a branch whose
|
|
623
|
-
* message contains the text (git log runs at the hub root), an action that is done, a path relative to the hub root that exists (`..` reaches sibling repositories).
|
|
623
|
+
* message contains the text (git log runs at the hub root), an action that is done, a path relative to the hub root that exists (`..` reaches sibling repositories), a mainline of this hub or a registered hub that is done.
|
|
624
624
|
*/
|
|
625
625
|
export declare const UNTIL: readonly {
|
|
626
626
|
kind: Until['kind'];
|
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-
|
|
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";
|
|
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 = {
|
|
@@ -115,7 +115,7 @@ const COMMAND_SPECS = {
|
|
|
115
115
|
},
|
|
116
116
|
"new mainline": {
|
|
117
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; --role plan makes it the mainline that splits the work, coordinates it and makes the final check (without --role it is an impl mainline)",
|
|
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)",
|
|
119
119
|
args: 1,
|
|
120
120
|
needsHub: true
|
|
121
121
|
},
|
|
@@ -133,7 +133,7 @@ const COMMAND_SPECS = {
|
|
|
133
133
|
},
|
|
134
134
|
"new issue": {
|
|
135
135
|
usage: "new issue <slug> --title <title> [--origin <ref>] [--labels a,b] [--group <w>] [--priority P0|P1|P2|P3]",
|
|
136
|
-
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",
|
|
136
|
+
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, in this hub or another registered one ({hub}:w001)",
|
|
137
137
|
args: 1,
|
|
138
138
|
needsHub: true
|
|
139
139
|
},
|
|
@@ -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 (--all includes done groups)",
|
|
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)",
|
|
161
161
|
args: 0,
|
|
162
162
|
needsHub: true
|
|
163
163
|
},
|
|
164
164
|
"mainline set": {
|
|
165
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",
|
|
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",
|
|
167
167
|
args: 1,
|
|
168
168
|
needsHub: true
|
|
169
169
|
},
|
|
@@ -283,7 +283,7 @@ const COMMAND_SPECS = {
|
|
|
283
283
|
},
|
|
284
284
|
"issue set": {
|
|
285
285
|
usage: "issue set <i> [--group <w|none>] [--priority P0|P1|P2|P3]",
|
|
286
|
-
summary: "Put an issue in a group, or take it out with --group none, and change its priority",
|
|
286
|
+
summary: "Put an issue in a group (of this hub, or {hub}:w001 of another registered one), or take it out with --group none, and change its priority",
|
|
287
287
|
args: 1,
|
|
288
288
|
needsHub: true
|
|
289
289
|
},
|
|
@@ -538,7 +538,7 @@ const RETRO_FORMATS = {
|
|
|
538
538
|
};
|
|
539
539
|
/**
|
|
540
540
|
* Conditions a blocked action's `until` takes and `wait` checks, one example each: a commit on a branch whose
|
|
541
|
-
* message contains the text (git log runs at the hub root), an action that is done, a path relative to the hub root that exists (`..` reaches sibling repositories).
|
|
541
|
+
* message contains the text (git log runs at the hub root), an action that is done, a path relative to the hub root that exists (`..` reaches sibling repositories), a mainline of this hub or a registered hub that is done.
|
|
542
542
|
*/
|
|
543
543
|
const UNTIL = UNTIL_FORMS;
|
|
544
544
|
/** Relation types a document's links take; readers derive the reverse direction. */
|
|
@@ -654,7 +654,7 @@ const LIST_ITEM = [
|
|
|
654
654
|
const FIELDS = {
|
|
655
655
|
mainline: [
|
|
656
656
|
...shared(...EVERY),
|
|
657
|
-
field("group", false, "所屬的組 w{NNN},一條主脈絡最多一組;組和依賴無關"),
|
|
657
|
+
field("group", false, "所屬的組 w{NNN},或其他 hub 的組 {hub}:w{NNN},一條主脈絡最多一組;組和依賴無關"),
|
|
658
658
|
field("role", false, "plan 是拆分顆粒、整合調度與最終確認的規劃型,impl 是執行的實作型;沒填視為 impl"),
|
|
659
659
|
field("due", false, "預計完成的日期"),
|
|
660
660
|
field("archivedAt", false, "封存的日期,和狀態分開"),
|
|
@@ -690,7 +690,7 @@ const FIELDS = {
|
|
|
690
690
|
],
|
|
691
691
|
issue: [
|
|
692
692
|
...shared(...EVERY),
|
|
693
|
-
field("group", false, "所屬的組 w{NNN},一筆待辦最多一組;同組的待辦在同一個時機一起做"),
|
|
693
|
+
field("group", false, "所屬的組 w{NNN},或其他 hub 的組 {hub}:w{NNN},一筆待辦最多一組;同組的待辦在同一個時機一起做"),
|
|
694
694
|
field("order", false, "待辦之間的順序"),
|
|
695
695
|
field("due", false, "預計完成的日期"),
|
|
696
696
|
field("plannedIn", false, "排進的任務,planned 時必填"),
|
package/dist/grant-commands.d.ts
CHANGED
package/dist/grant-commands.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { nt as GRANT_FORMS } from "./dist-
|
|
1
|
+
import { nt as GRANT_FORMS } from "./dist-ud09dzZo.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-
|
|
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";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region ../core/dist/ids/allocators.d.ts
|
|
4
4
|
/** The letters ids start with. */
|
package/dist/hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { F as configSchema, it as describeRequest } from "./dist-
|
|
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,
|
|
3
|
-
import { n as hubWriter, r as writtenLines } from "./operation-
|
|
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";
|
|
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";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as OFFSET, A as SURVEY_SECTION, B as issueSchema, C as REF_EXAMPLES, D as SESSION_STATUS, E as SESSION_ID, F as configSchema, G as parseRef, H as opsEntrySchema, I as decisionSchema, J as refMainline, K as parseUntil, L as findingSchema, M as TASK_SECTIONS, O as SLUG, P as WORK_STATUS, Q as waitingForRef, R as formatOpsEntry, S as PRIORITIES, T as SERVES_REF, U as parseActionRef, V as mainlineSchema, W as parseOpsLine, X as taskSchema, Y as sessionSchema, Z as waitingForAction, a as DECISION_SECTIONS, at as grantCovers, b as MAINLINE_STATUS, ct as parseGrantTarget, et as stampMs, f as GROUP_SECTIONS, h as ISSUE_SECTIONS, i as DECISION_BASES, it as describeRequest, j as TASK_REQUIRED_SECTIONS, k as SURVEY_LINES, l as FINDING_SECTIONS, n as CLOSED_STATUS, ot as grantForm, p as GROUP_STATUS, q as refExample, r as DECIDERS, s as DEFAULT_CATEGORIES, st as grantRepo, u as FINDING_STATUS, v as MAINLINE_ROLES, w as RESERVED_HUB_NAMES, x as MERGE_STATES, y as MAINLINE_SECTIONS, z as groupSchema } from "./dist-
|
|
1
|
+
import { $ as OFFSET, A as SURVEY_SECTION, B as issueSchema, C as REF_EXAMPLES, D as SESSION_STATUS, E as SESSION_ID, F as configSchema, G as parseRef, H as opsEntrySchema, I as decisionSchema, J as refMainline, K as parseUntil, L as findingSchema, M as TASK_SECTIONS, N as UNTIL_FORMS, O as SLUG, P as WORK_STATUS, Q as waitingForRef, R as formatOpsEntry, S as PRIORITIES, T as SERVES_REF, U as parseActionRef, V as mainlineSchema, W as parseOpsLine, X as taskSchema, Y as sessionSchema, Z as waitingForAction, a as DECISION_SECTIONS, at as grantCovers, b as MAINLINE_STATUS, ct as parseGrantTarget, et as stampMs, f as GROUP_SECTIONS, h as ISSUE_SECTIONS, i as DECISION_BASES, it as describeRequest, j as TASK_REQUIRED_SECTIONS, k as SURVEY_LINES, l as FINDING_SECTIONS, n as CLOSED_STATUS, ot as grantForm, p as GROUP_STATUS, q as refExample, r as DECIDERS, s as DEFAULT_CATEGORIES, st as grantRepo, u as FINDING_STATUS, v as MAINLINE_ROLES, w as RESERVED_HUB_NAMES, x as MERGE_STATES, y as MAINLINE_SECTIONS, z as groupSchema } from "./dist-ud09dzZo.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
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, symlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
@@ -618,6 +618,7 @@ const mainlineDir = (root, id) => onDisk(root, mainlineDirIn(nodeStorage(root),
|
|
|
618
618
|
const taskDir = (root, mainline, task) => onDisk(root, taskDirIn(nodeStorage(root), mainline, task));
|
|
619
619
|
const mainlineFile = (root, id) => join(mainlineDir(root, id), MAINLINE_FILE);
|
|
620
620
|
const taskFile = (root, mainline, task) => join(taskDir(root, mainline, task), TASK_FILE);
|
|
621
|
+
const readConfig = (root) => readConfigIn(nodeStorage(root));
|
|
621
622
|
//#endregion
|
|
622
623
|
//#region ../core/dist/refs.js
|
|
623
624
|
const itemStatus = (item) => item.done ? "done" : item.dropped ? "dropped" : "open";
|
|
@@ -706,6 +707,64 @@ function linksInto(hub, hubName) {
|
|
|
706
707
|
for (const g of hub.groups) add(g.id, g.links);
|
|
707
708
|
return out;
|
|
708
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Where a member's `group` value points: `id` is the group's id, and `hub` is the other hub's name, or undefined
|
|
712
|
+
* for a group of the member's own hub (no prefix, or the member's own hub name as prefix).
|
|
713
|
+
*/
|
|
714
|
+
function splitGroup(value, ownHub) {
|
|
715
|
+
const colon = value.indexOf(":");
|
|
716
|
+
if (colon < 0) return { id: value };
|
|
717
|
+
const hub = value.slice(0, colon);
|
|
718
|
+
const id = value.slice(colon + 1);
|
|
719
|
+
return hub === ownHub ? { id } : {
|
|
720
|
+
hub,
|
|
721
|
+
id
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
/** Whether a member's `group` value names the group `groupId` of its own hub `ownHub`: `w001` or `{ownHub}:w001`. */
|
|
725
|
+
function memberOfGroup(group, groupId, ownHub) {
|
|
726
|
+
if (group === void 0) return false;
|
|
727
|
+
const target = splitGroup(group, ownHub);
|
|
728
|
+
return target.hub === void 0 && target.id === groupId;
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* The mainlines and issues of the registered hubs whose `group` names one of `hubName`'s groups, by group id. Only
|
|
732
|
+
* the hubs' own documents are read, one level, so a hub that is not on this machine contributes nothing.
|
|
733
|
+
*/
|
|
734
|
+
function remoteMembers(remotes, hubName) {
|
|
735
|
+
const out = /* @__PURE__ */ new Map();
|
|
736
|
+
const add = (group, member) => {
|
|
737
|
+
if (!group) return;
|
|
738
|
+
const target = splitGroup(group, member.hub);
|
|
739
|
+
if (target.hub !== hubName) return;
|
|
740
|
+
out.set(target.id, [...out.get(target.id) ?? [], member]);
|
|
741
|
+
};
|
|
742
|
+
for (const r of remotes) {
|
|
743
|
+
if (!r.hub) continue;
|
|
744
|
+
for (const m of r.hub.mainlines) add(m.group, {
|
|
745
|
+
ref: `${r.name}:${m.id}`,
|
|
746
|
+
hub: r.name,
|
|
747
|
+
kind: "mainline",
|
|
748
|
+
title: m.title,
|
|
749
|
+
status: m.status,
|
|
750
|
+
role: m.role ?? "impl",
|
|
751
|
+
archived: Boolean(m.archivedAt),
|
|
752
|
+
open: !CLOSED_STATUS.mainline.includes(m.status)
|
|
753
|
+
});
|
|
754
|
+
for (const i of r.hub.issues) add(i.group, {
|
|
755
|
+
ref: `${r.name}:${i.id}`,
|
|
756
|
+
hub: r.name,
|
|
757
|
+
kind: "issue",
|
|
758
|
+
title: i.title,
|
|
759
|
+
status: i.status,
|
|
760
|
+
archived: Boolean(i.archivedAt),
|
|
761
|
+
open: i.status !== "closed"
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
return out;
|
|
765
|
+
}
|
|
766
|
+
/** The registered hubs that could not be loaded, for a reader that must say its member list may be incomplete. */
|
|
767
|
+
const unavailableHubs = (remotes) => remotes.filter((r) => r.unavailable).map((r) => r.name);
|
|
709
768
|
//#endregion
|
|
710
769
|
//#region ../core/dist/deps.js
|
|
711
770
|
const MET = /* @__PURE__ */ new Set([
|
|
@@ -1165,8 +1224,7 @@ function loadHub(root, options = {}) {
|
|
|
1165
1224
|
}
|
|
1166
1225
|
const findings = hubDocs(join(dataDir, "findings"), findingSchema);
|
|
1167
1226
|
const groups = hubDocs(join(dataDir, "groups"), groupSchema);
|
|
1168
|
-
problems.push(...groupProblems(groups, mainlines, hubIssues, unreadable));
|
|
1169
|
-
warnings.push(...groupWarnings(groups, mainlines, hubIssues));
|
|
1227
|
+
problems.push(...groupProblems(config.hub, groups, mainlines, hubIssues, unreadable));
|
|
1170
1228
|
const ops = [];
|
|
1171
1229
|
const opsPath = join(dataDir, "ops");
|
|
1172
1230
|
for (const name of existsSync(opsPath) ? readdirSync(opsPath).filter((n) => n.endsWith(".log")).sort() : []) readFileSync(join(opsPath, name), "utf8").split("\n").forEach((line, index) => {
|
|
@@ -1185,6 +1243,12 @@ function loadHub(root, options = {}) {
|
|
|
1185
1243
|
});
|
|
1186
1244
|
});
|
|
1187
1245
|
const remotes = options.remotes === false ? [] : loadRemotes(root, config, problems, warnings);
|
|
1246
|
+
warnings.push(...groupWarnings(config.hub, groups, mainlines, hubIssues, remotes));
|
|
1247
|
+
for (const doc of [...mainlines, ...hubIssues]) if (doc.group && splitGroup(doc.group, config.hub).hub !== void 0) pending.push({
|
|
1248
|
+
ref: doc.group,
|
|
1249
|
+
file: doc.file,
|
|
1250
|
+
field: "group"
|
|
1251
|
+
});
|
|
1188
1252
|
checkReferences({
|
|
1189
1253
|
config,
|
|
1190
1254
|
mainlines,
|
|
@@ -1238,20 +1302,32 @@ function loadHub(root, options = {}) {
|
|
|
1238
1302
|
remotes
|
|
1239
1303
|
};
|
|
1240
1304
|
}
|
|
1241
|
-
/** Members name their group; one that names a group this hub does not have is reported on the member. */
|
|
1242
|
-
function groupProblems(groups, mainlines, issues, unreadable) {
|
|
1305
|
+
/** Members name their group; one that names a group this hub does not have is reported on the member. A group of another hub is checked with the other references. */
|
|
1306
|
+
function groupProblems(hubName, groups, mainlines, issues, unreadable) {
|
|
1243
1307
|
const known = new Set(groups.map((g) => g.id));
|
|
1244
|
-
return [...mainlines, ...issues].flatMap((doc) =>
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1308
|
+
return [...mainlines, ...issues].flatMap((doc) => {
|
|
1309
|
+
if (!doc.group) return [];
|
|
1310
|
+
const { hub, id } = splitGroup(doc.group, hubName);
|
|
1311
|
+
return hub === void 0 && !known.has(id) && !unreadable.has(id) ? [{
|
|
1312
|
+
file: doc.file,
|
|
1313
|
+
field: "group",
|
|
1314
|
+
message: `group ${doc.group} does not exist; create it with "mainflow new group <slug> --title <title>" or name an existing one`
|
|
1315
|
+
}] : [];
|
|
1316
|
+
});
|
|
1249
1317
|
}
|
|
1250
|
-
/**
|
|
1251
|
-
|
|
1318
|
+
/**
|
|
1319
|
+
* A group marked done while some of its members are still open: a plan to settle, not a broken file. Members in
|
|
1320
|
+
* other hubs count too, when those hubs are on this machine.
|
|
1321
|
+
*/
|
|
1322
|
+
function groupWarnings(hubName, groups, mainlines, issues, remotes) {
|
|
1323
|
+
const remote = remoteMembers(remotes, hubName);
|
|
1252
1324
|
return groups.flatMap((g) => {
|
|
1253
1325
|
if (g.status !== "done") return [];
|
|
1254
|
-
const open = [
|
|
1326
|
+
const open = [
|
|
1327
|
+
...mainlines.filter((m) => memberOfGroup(m.group, g.id, hubName) && isOpen$2("mainline", m.status)).map((m) => m.id),
|
|
1328
|
+
...issues.filter((i) => memberOfGroup(i.group, g.id, hubName) && i.status !== "closed").map((i) => i.id),
|
|
1329
|
+
...(remote.get(g.id) ?? []).filter((m) => m.open).map((m) => m.ref)
|
|
1330
|
+
];
|
|
1255
1331
|
return open.length ? [{
|
|
1256
1332
|
file: g.file,
|
|
1257
1333
|
field: "status",
|
|
@@ -1648,12 +1724,18 @@ function requireExisting(hub, ref) {
|
|
|
1648
1724
|
/** A priority as a command gives it, checked against P0 to P3. */
|
|
1649
1725
|
const requirePriority = (value) => requireOneOf(value, PRIORITIES, "priority");
|
|
1650
1726
|
/**
|
|
1651
|
-
* The group a member names, which must exist
|
|
1652
|
-
*
|
|
1727
|
+
* The group a member names: one of this hub, which must exist, or one of another hub (`other-hub:w001`), which
|
|
1728
|
+
* only needs that hub registered here; the commands check the group itself when that hub is on this machine.
|
|
1729
|
+
* The hub's own name as prefix gives the group without it. `none` clears the membership; `null` is how a patch
|
|
1730
|
+
* says the same, so a command can pass the word and an interface the value.
|
|
1653
1731
|
*/
|
|
1654
1732
|
function requireGroup(hub, value) {
|
|
1655
1733
|
const ref = requireRef(value, "group");
|
|
1656
|
-
|
|
1734
|
+
const config = readConfigIn(hub);
|
|
1735
|
+
if (ref.hub !== void 0 && ref.hub !== config.hub) {
|
|
1736
|
+
if (!config.hubs?.[ref.hub]) throw new WriteError(`hub "${ref.hub}" is not registered; run "mainflow hub add ${ref.hub} <path>" first`);
|
|
1737
|
+
return `${ref.hub}:${ref.group}`;
|
|
1738
|
+
}
|
|
1657
1739
|
entryFile(hub, GROUPS_DIR, ref.group, "group");
|
|
1658
1740
|
return ref.group;
|
|
1659
1741
|
}
|
|
@@ -2692,6 +2774,7 @@ function addAction(hub, input, ctx) {
|
|
|
2692
2774
|
* to work that has since been handed off to this very action would otherwise wait forever.
|
|
2693
2775
|
*/
|
|
2694
2776
|
function requireBlock(hub, ref, block) {
|
|
2777
|
+
if (block.until !== void 0) requireMainlineTarget(hub, block.until);
|
|
2695
2778
|
const targets = [waitingForAction(block.waitingFor), block.until === void 0 ? void 0 : untilTarget(block.until)];
|
|
2696
2779
|
for (const target of targets) {
|
|
2697
2780
|
if (!target) continue;
|
|
@@ -2700,10 +2783,23 @@ function requireBlock(hub, ref, block) {
|
|
|
2700
2783
|
if (found.ref === ref) throw new WriteError(`action ${ref} cannot wait for itself${target === ref ? "" : ` (${target} was handed off to it)`}`);
|
|
2701
2784
|
}
|
|
2702
2785
|
}
|
|
2786
|
+
/** A `mainline-done` condition has to name a mainline in this hub, or a hub registered here. */
|
|
2787
|
+
function requireMainlineTarget(hub, until) {
|
|
2788
|
+
const parsed = parseUntil(until);
|
|
2789
|
+
if (parsed?.kind !== "mainline-done") return;
|
|
2790
|
+
const ref = parseRef(parsed.mainline);
|
|
2791
|
+
if (ref?.kind !== "mainline") return;
|
|
2792
|
+
const config = readConfigIn(hub);
|
|
2793
|
+
if (ref.hub !== void 0 && ref.hub !== config.hub) {
|
|
2794
|
+
if (!config.hubs?.[ref.hub]) throw new WriteError(`hub "${ref.hub}" is not registered; run "mainflow hub add ${ref.hub} <path>" first`);
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
mainlineDirIn(hub, ref.mainline);
|
|
2798
|
+
}
|
|
2703
2799
|
/** The action an `until` waits for; throws when the condition matches none of the forms. */
|
|
2704
2800
|
function untilTarget(until) {
|
|
2705
2801
|
const parsed = parseUntil(until);
|
|
2706
|
-
if (!parsed) throw new WriteError(`--until takes a condition like
|
|
2802
|
+
if (!parsed) throw new WriteError(`--until takes a condition like ${UNTIL_FORMS.map((f) => f.format).join(", ")}, got "${until}"`);
|
|
2707
2803
|
return parsed.kind === "action-done" ? `${parsed.session}#${parsed.action}` : void 0;
|
|
2708
2804
|
}
|
|
2709
2805
|
function updateAction(hub, input, ctx) {
|
|
@@ -3917,11 +4013,78 @@ function actionState(root, ref) {
|
|
|
3917
4013
|
detail: `${ref}${via} is ${found.action.status}`
|
|
3918
4014
|
};
|
|
3919
4015
|
}
|
|
4016
|
+
/**
|
|
4017
|
+
* Whether a mainline is done. It can no longer come true when the mainline was dropped, does not exist, or its
|
|
4018
|
+
* hub is not registered here. A registered hub that is missing on this machine or fails to load may return, so
|
|
4019
|
+
* that case keeps waiting. A prefix equal to this hub's own name reads the local hub.
|
|
4020
|
+
*/
|
|
4021
|
+
function mainlineState(root, text) {
|
|
4022
|
+
const ref = parseRef(text);
|
|
4023
|
+
if (ref?.kind !== "mainline") return {
|
|
4024
|
+
met: false,
|
|
4025
|
+
unreachable: true,
|
|
4026
|
+
detail: `"${text}" is not a mainline reference like m001 or other-hub:m001`
|
|
4027
|
+
};
|
|
4028
|
+
let target = root;
|
|
4029
|
+
try {
|
|
4030
|
+
const config = readConfig(root);
|
|
4031
|
+
if (ref.hub !== void 0 && ref.hub !== config.hub) {
|
|
4032
|
+
const path = config.hubs?.[ref.hub];
|
|
4033
|
+
if (path === void 0) return {
|
|
4034
|
+
met: false,
|
|
4035
|
+
unreachable: true,
|
|
4036
|
+
detail: `hub "${ref.hub}" is not registered, so ${text} can never be read; run "mainflow hub add ${ref.hub} <path>"`
|
|
4037
|
+
};
|
|
4038
|
+
target = remoteRoot(root, path);
|
|
4039
|
+
if (!isHubRoot(target)) return {
|
|
4040
|
+
met: false,
|
|
4041
|
+
detail: `hub "${ref.hub}" is not at ${path} on this machine, so ${text} cannot be read yet`
|
|
4042
|
+
};
|
|
4043
|
+
}
|
|
4044
|
+
} catch (error) {
|
|
4045
|
+
return {
|
|
4046
|
+
met: false,
|
|
4047
|
+
detail: `the hub config cannot be read, so ${text} cannot be checked: ${error.message}`
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
try {
|
|
4051
|
+
mainlineDir(target, ref.mainline);
|
|
4052
|
+
} catch {
|
|
4053
|
+
return {
|
|
4054
|
+
met: false,
|
|
4055
|
+
unreachable: true,
|
|
4056
|
+
detail: `mainline ${text} does not exist, so it will never be done`
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
4059
|
+
let status;
|
|
4060
|
+
try {
|
|
4061
|
+
status = readFrontMatter(mainlineFile(target, ref.mainline), mainlineSchema).data.status;
|
|
4062
|
+
} catch (error) {
|
|
4063
|
+
return {
|
|
4064
|
+
met: false,
|
|
4065
|
+
detail: `mainline ${text} cannot be read yet: ${error.message}`
|
|
4066
|
+
};
|
|
4067
|
+
}
|
|
4068
|
+
if (status === "done") return {
|
|
4069
|
+
met: true,
|
|
4070
|
+
detail: `mainline ${text} is done`
|
|
4071
|
+
};
|
|
4072
|
+
if (status === "dropped") return {
|
|
4073
|
+
met: false,
|
|
4074
|
+
unreachable: true,
|
|
4075
|
+
detail: `mainline ${text} was dropped, so it will never be done`
|
|
4076
|
+
};
|
|
4077
|
+
return {
|
|
4078
|
+
met: false,
|
|
4079
|
+
detail: `mainline ${text} is ${status}`
|
|
4080
|
+
};
|
|
4081
|
+
}
|
|
3920
4082
|
/** Check a wait condition once. */
|
|
3921
4083
|
function untilState(root, until) {
|
|
3922
4084
|
switch (until.kind) {
|
|
3923
4085
|
case "commit": return commitState(root, until.branch, until.text);
|
|
3924
4086
|
case "action-done": return actionState(root, `${until.session}#${until.action}`);
|
|
4087
|
+
case "mainline-done": return mainlineState(root, until.mainline);
|
|
3925
4088
|
case "file": return existsSync(resolve(root, until.path)) ? {
|
|
3926
4089
|
met: true,
|
|
3927
4090
|
detail: `${until.path} exists`
|
|
@@ -7939,4 +8102,4 @@ function openInApp(hub, target, closeAfterMs = 150) {
|
|
|
7939
8102
|
return true;
|
|
7940
8103
|
}
|
|
7941
8104
|
//#endregion
|
|
7942
|
-
export {
|
|
8105
|
+
export { nowMinute as $, mayDecorate as A, applyOperation as B, readSession as C, splitFrontMatter as Ct, decorateReply as D, matchGrants as E, renumberRequest as F, sectionText as G, HubError as H, renumberFiles as I, linksInto as J, dependencyGraph as K, renumberPath as L, traceTranscript as M, transcriptTitle as N, endsWithMarker as O, applyOffline as P, unavailableHubs as Q, renumberText as R, loadSessions as S, contentHash as St, grantScope as T, loadConfig as U, checkHubName as V, loadHub as W, refIndex as X, memberOfGroup as Y, remoteMembers as Z, initHub as _, findHubRoot as _t, openInApp as a, MAX_FILE_BYTES as at, sessionBriefing as b, DATA_DIR as bt, siteBlock as c, comparePaths as ct, retroReport as d, requestTime as dt, readYaml as et, retroReportFromReceiver as f, textBytes as ft, setArchivedMany as g, currentBranch as gt, ARCHIVE_KINDS as h, requireSlug as ht, hostName as i, MAX_BLOB_BYTES as it, attributeTrace as j, headerLine as k, syncHost as l, exceedsFileLimit as lt, RETRY_RULES as m, TASK_FILE as mt, DEFAULT_UI_PORT as n, ACCESS_HEADERS as nt, removeDanglingLinks as o, ROUTES as ot, receiverFromEnv as p, MAINLINE_FILE as pt, mainlineEdges as q, caddySites as r, BLOB_HASH as rt, removeHostLink as s, SOCKET_MAX_AGE_CLOSE as st, APP_BUNDLE_ID as t, nodeStorage as tt, migrateHub as u, readsAsText as ut, untilState as v, worktreesOf as vt, transcriptPath as w, turnReminder as x, WriteError as xt, duplicateClaimLines as y, ConflictError as yt, scopeOfPath as z };
|
package/dist/host.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as openInApp, c as siteBlock, i as hostName, l as syncHost, n as DEFAULT_UI_PORT, o as removeDanglingLinks, r as caddySites, s as removeHostLink, t as APP_BUNDLE_ID } from "./host-
|
|
1
|
+
import { a as openInApp, c as siteBlock, i as hostName, l as syncHost, n as DEFAULT_UI_PORT, o as removeDanglingLinks, r as caddySites, s as removeHostLink, t as APP_BUNDLE_ID } from "./host-BauijAdm.js";
|
|
2
2
|
export { APP_BUNDLE_ID, DEFAULT_UI_PORT, caddySites, hostName, openInApp, removeDanglingLinks, removeHostLink, siteBlock, syncHost };
|
|
@@ -250,7 +250,8 @@ type Task = z.infer<typeof taskSchema>;
|
|
|
250
250
|
/**
|
|
251
251
|
* A condition a program can check, written `{kind}:{argument}`. `commit` holds once a commit message on the
|
|
252
252
|
* branch contains the text, `action-done` once the action is done, `file` once the path exists under the hub
|
|
253
|
-
* root
|
|
253
|
+
* root, `mainline-done` once the mainline (`m{NNN}` or `{hub}:m{NNN}`) is done. Git branch names cannot contain a
|
|
254
|
+
* colon, so the text after the branch may.
|
|
254
255
|
*/
|
|
255
256
|
type Until = {
|
|
256
257
|
kind: 'commit';
|
|
@@ -263,6 +264,9 @@ type Until = {
|
|
|
263
264
|
} | {
|
|
264
265
|
kind: 'file';
|
|
265
266
|
path: string;
|
|
267
|
+
} | {
|
|
268
|
+
kind: 'mainline-done';
|
|
269
|
+
mainline: string;
|
|
266
270
|
};
|
|
267
271
|
/**
|
|
268
272
|
* Why a blocked action cannot move, what it waits for, and the condition a program checks to end the wait.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bt as DATA_DIR, i as hostName, l as syncHost, n as DEFAULT_UI_PORT, s as removeHostLink, xt as WriteError } from "./host-BauijAdm.js";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -276,7 +276,7 @@ async function launchUi(root, hub, configured, options) {
|
|
|
276
276
|
}
|
|
277
277
|
let server;
|
|
278
278
|
if (!reuse) {
|
|
279
|
-
const { serveUi } = await import("./ui-
|
|
279
|
+
const { serveUi } = await import("./ui-C-laSyqU.js");
|
|
280
280
|
server = await serveUi(root, choice.port);
|
|
281
281
|
writeUiRecord(root, {
|
|
282
282
|
port: choice.port,
|
package/dist/launch.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as networkProbe, c as realRoot, d as withUiLock, i as launchUi, l as startUiInBackground, n as choosePort, o as portCandidates, r as exitCodeFor, s as readUiRecord, t as PORT_SPAN, u as watchHubGone } from "./launch-
|
|
1
|
+
import { a as networkProbe, c as realRoot, d as withUiLock, i as launchUi, l as startUiInBackground, n as choosePort, o as portCandidates, r as exitCodeFor, s as readUiRecord, t as PORT_SPAN, u as watchHubGone } from "./launch-n2ZDF0BF.js";
|
|
2
2
|
export { PORT_SPAN, choosePort, exitCodeFor, launchUi, networkProbe, portCandidates, readUiRecord, realRoot, startUiInBackground, watchHubGone, withUiLock };
|