mainflow 0.21.0 → 0.22.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 +16 -8
- package/dist/{dist-BrotcvKi.js → dist-DCYzrl7J.js} +367 -3
- package/dist/facts.d.ts +23 -27
- package/dist/facts.js +22 -3
- package/dist/grant-commands.d.ts +73 -0
- package/dist/grant-commands.js +245 -0
- package/dist/hooks.d.ts +23 -2
- package/dist/hooks.js +166 -12
- package/dist/{host-BsLqiI0_.js → host-0_zkFbzM.js} +172 -13
- package/dist/host.js +1 -1
- package/dist/index-CV30LkNZ.d.ts +27 -0
- package/dist/{launch-CBXoFsFC.js → launch-B8-NVG2g.js} +2 -2
- package/dist/launch.js +1 -1
- package/dist/{ui-ngIAww3a.js → ui-hvirfamo.js} +2 -2
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { A as formatOpsEntry, B as waitingForRef, C as SURVEY_SECTION, D as configSchema, E as WORK_STATUS, F as parseRef, I as refExample, L as refMainline, M as mainlineSchema, N as opsEntrySchema, O as decisionSchema, P as parseOpsLine, R as sessionSchema, S as SURVEY_LINES, T as TASK_SECTIONS, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, j as issueSchema, k as findingSchema, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, v as REF_EXAMPLES, w as TASK_REQUIRED_SECTIONS, x as SLUG, y as RESERVED_HUB_NAMES, z as taskSchema } from "./dist-
|
|
1
|
+
import { A as formatOpsEntry, B as waitingForRef, C as SURVEY_SECTION, D as configSchema, E as WORK_STATUS, F as parseRef, G as grantCovers, I as refExample, J as parseGrantTarget, K as grantForm, L as refMainline, M as mainlineSchema, N as opsEntrySchema, O as decisionSchema, P as parseOpsLine, R as sessionSchema, S as SURVEY_LINES, T as TASK_SECTIONS, W as describeRequest, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, j as issueSchema, k as findingSchema, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, q as grantRepo, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, v as REF_EXAMPLES, w as TASK_REQUIRED_SECTIONS, x as SLUG, y as RESERVED_HUB_NAMES, z as taskSchema } from "./dist-DCYzrl7J.js";
|
|
2
2
|
import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
3
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { spawn, spawnSync } from "node:child_process";
|
|
5
5
|
import { createHash, randomBytes } from "node:crypto";
|
|
6
|
-
import { parse, stringify } from "yaml";
|
|
6
|
+
import { parse as parse$1, stringify } from "yaml";
|
|
7
7
|
//#region ../core/dist/paths.js
|
|
8
8
|
const DATA_DIR = ".mainflow";
|
|
9
9
|
const ENTRY_DIR = /^([mtdif]\d{3})-(.+)$/;
|
|
@@ -64,7 +64,7 @@ function splitFrontMatter(source) {
|
|
|
64
64
|
body: source
|
|
65
65
|
};
|
|
66
66
|
return {
|
|
67
|
-
data: parse(match[1] ?? ""),
|
|
67
|
+
data: parse$1(match[1] ?? ""),
|
|
68
68
|
body: source.slice(match[0].length)
|
|
69
69
|
};
|
|
70
70
|
}
|
|
@@ -145,7 +145,7 @@ const toYaml = (data) => stringify(data, { lineWidth: 0 });
|
|
|
145
145
|
function readYaml(file, schema) {
|
|
146
146
|
const text = readFileSync(file, "utf8");
|
|
147
147
|
return {
|
|
148
|
-
data: validate(schema, parse(text), file),
|
|
148
|
+
data: validate(schema, parse$1(text), file),
|
|
149
149
|
version: contentHash(text)
|
|
150
150
|
};
|
|
151
151
|
}
|
|
@@ -154,7 +154,7 @@ function mutateYaml(root, file, schema, mutate, expectedVersion) {
|
|
|
154
154
|
return withLock(root, () => {
|
|
155
155
|
const text = readFileSync(file, "utf8");
|
|
156
156
|
if (expectedVersion && contentHash(text) !== expectedVersion) throw new ConflictError(`${file} changed since it was read; reload and retry`);
|
|
157
|
-
const data = validate(schema, parse(text), file);
|
|
157
|
+
const data = validate(schema, parse$1(text), file);
|
|
158
158
|
mutate(data);
|
|
159
159
|
const next = validate(schema, data, file);
|
|
160
160
|
writeAtomic(file, toYaml(next));
|
|
@@ -491,7 +491,7 @@ function loadHub(root, options = {}) {
|
|
|
491
491
|
const read = (file, schema, raw) => {
|
|
492
492
|
let data = raw;
|
|
493
493
|
if (data === void 0) try {
|
|
494
|
-
data = parse(readText(file) ?? "");
|
|
494
|
+
data = parse$1(readText(file) ?? "");
|
|
495
495
|
} catch (error) {
|
|
496
496
|
problems.push({
|
|
497
497
|
file: rel(file),
|
|
@@ -520,6 +520,7 @@ function loadHub(root, options = {}) {
|
|
|
520
520
|
const config = read(join(dataDir, "config.yaml"), configSchema);
|
|
521
521
|
if (!config) throw new HubError("invalid config.yaml", problems);
|
|
522
522
|
if (config.formatVersion !== 2) throw new HubError(config.formatVersion < 2 ? `data format version ${config.formatVersion} is older than this CLI's (2); run "mainflow migrate --dry-run" to preview the conversion, then "mainflow migrate"` : `data format version ${config.formatVersion} is newer than this CLI supports (2); install the matching mainflow version in this hub`, problems);
|
|
523
|
+
problems.push(...repoPathProblems(root, config));
|
|
523
524
|
const categories = /* @__PURE__ */ new Set([...DEFAULT_CATEGORIES, ...config.categories ?? []]);
|
|
524
525
|
/** Read a Markdown document's front matter against `schema`, with the attributes every document shares. */
|
|
525
526
|
const readDocument = (file, schema) => {
|
|
@@ -568,6 +569,7 @@ function loadHub(root, options = {}) {
|
|
|
568
569
|
continue;
|
|
569
570
|
}
|
|
570
571
|
checkDirName(mainlineDir, mainline.id);
|
|
572
|
+
problems.push(...grantProblems(mainline, config));
|
|
571
573
|
const decisions = [];
|
|
572
574
|
const decisionsDir = join(mainlineDir, "decisions");
|
|
573
575
|
for (const name of existsSync(decisionsDir) ? readdirSync(decisionsDir).filter((n) => n.endsWith(".md")).sort() : []) {
|
|
@@ -873,6 +875,57 @@ function checkReferences(input) {
|
|
|
873
875
|
});
|
|
874
876
|
}
|
|
875
877
|
}
|
|
878
|
+
/**
|
|
879
|
+
* A listed repository counts as part of the hub, so the PreToolUse hook lets grants act inside it. A path that
|
|
880
|
+
* resolves to / or to a directory above the hub would put everything under it in scope. A path that does not
|
|
881
|
+
* exist is fine: another machine may not have cloned that repository yet.
|
|
882
|
+
*/
|
|
883
|
+
function repoPathProblems(root, config) {
|
|
884
|
+
const real = (path) => {
|
|
885
|
+
try {
|
|
886
|
+
return realpathSync(path);
|
|
887
|
+
} catch {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
const hub = real(root) ?? root;
|
|
892
|
+
return Object.entries(config.repos).flatMap(([name, path]) => {
|
|
893
|
+
const dir = real(resolve(root, path));
|
|
894
|
+
if (dir === null) return [];
|
|
895
|
+
const problem = (message) => [{
|
|
896
|
+
file: `${DATA_DIR}/config.yaml`,
|
|
897
|
+
field: `repos.${name}`,
|
|
898
|
+
message
|
|
899
|
+
}];
|
|
900
|
+
if (dir === parse(dir).root) return problem(`"${path}" resolves to the file system root; list the repository's own directory`);
|
|
901
|
+
if (hub.startsWith(dir.endsWith(sep) ? dir : dir + sep)) return problem(`"${path}" resolves to ${dir}, above the hub; list the repository's own directory`);
|
|
902
|
+
return [];
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* What the schema cannot see about a mainline's grants: ids must be unique, since the file is edited directly,
|
|
907
|
+
* and a target that names a repository must name one listed in config.yaml.
|
|
908
|
+
*/
|
|
909
|
+
function grantProblems(mainline, config) {
|
|
910
|
+
const problems = [];
|
|
911
|
+
const seen = /* @__PURE__ */ new Set();
|
|
912
|
+
mainline.grants?.forEach((grant, i) => {
|
|
913
|
+
if (seen.has(grant.id)) problems.push({
|
|
914
|
+
file: mainline.file,
|
|
915
|
+
field: `grants.${i}.id`,
|
|
916
|
+
message: `${grant.id} is used twice; give it the next free id`
|
|
917
|
+
});
|
|
918
|
+
seen.add(grant.id);
|
|
919
|
+
const parsed = parseGrantTarget(grant.action, grant.target);
|
|
920
|
+
const repo = parsed.ok ? grantRepo(parsed.target) : void 0;
|
|
921
|
+
if (repo !== void 0 && !(repo in config.repos)) problems.push({
|
|
922
|
+
file: mainline.file,
|
|
923
|
+
field: `grants.${i}.target`,
|
|
924
|
+
message: `repo "${repo}" is not listed in config.yaml; use one of ${Object.keys(config.repos).join(", ") || "(none registered)"}`
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
return problems;
|
|
928
|
+
}
|
|
876
929
|
const isOpen$2 = (kind, status) => !CLOSED_STATUS[kind].includes(status);
|
|
877
930
|
/**
|
|
878
931
|
* What a reader without the conversation needs to pick the work up: an open mainline with tasks says what
|
|
@@ -1171,6 +1224,107 @@ function decorateReply(text, context) {
|
|
|
1171
1224
|
/** Cheap test for text that decorateReply could change, so a display hook can skip loading the hub. */
|
|
1172
1225
|
const mayDecorate = (text) => /m\d{3}|[if]\d{3}|\.mainflow\/mainlines/.test(text) || endsWithMarker(text);
|
|
1173
1226
|
//#endregion
|
|
1227
|
+
//#region ../core/dist/grants.js
|
|
1228
|
+
/** Mainline statuses whose grants apply. */
|
|
1229
|
+
const GRANTING_STATUS = ["active", "planning"];
|
|
1230
|
+
/**
|
|
1231
|
+
* The grants in effect for a session. Reading a mainline that is missing or invalid throws, so a caller that
|
|
1232
|
+
* must fail closed catches it and asks.
|
|
1233
|
+
*/
|
|
1234
|
+
function grantScope(root, session) {
|
|
1235
|
+
if (!session) return {
|
|
1236
|
+
ok: false,
|
|
1237
|
+
reason: "這場會話沒有 mainflow 紀錄"
|
|
1238
|
+
};
|
|
1239
|
+
const doing = session.actions.filter((a) => a.status === "doing");
|
|
1240
|
+
if (doing.length === 0) return {
|
|
1241
|
+
ok: false,
|
|
1242
|
+
reason: `${session.id} 沒有進行中的行動`
|
|
1243
|
+
};
|
|
1244
|
+
if (doing.length > 1) return {
|
|
1245
|
+
ok: false,
|
|
1246
|
+
reason: `${session.id} 同時有 ${doing.length} 個進行中的行動(${doing.map((a) => a.id).join("、")}),分不出授權範圍`
|
|
1247
|
+
};
|
|
1248
|
+
const action = doing[0];
|
|
1249
|
+
const mainlines = [...new Set(action.serves.flatMap((ref) => {
|
|
1250
|
+
const parsed = parseRef(ref);
|
|
1251
|
+
const mainline = parsed ? refMainline(parsed) : void 0;
|
|
1252
|
+
return mainline ? [mainline] : [];
|
|
1253
|
+
}))];
|
|
1254
|
+
if (mainlines.length === 0) return {
|
|
1255
|
+
ok: false,
|
|
1256
|
+
reason: `${action.id} 沒有服務任何 checklist 項目`
|
|
1257
|
+
};
|
|
1258
|
+
const grants = [];
|
|
1259
|
+
const served = {};
|
|
1260
|
+
const closed = [];
|
|
1261
|
+
for (const id of mainlines) {
|
|
1262
|
+
const mainline = readFrontMatter(mainlineFile(root, id), mainlineSchema).data;
|
|
1263
|
+
if (!GRANTING_STATUS.includes(mainline.status)) {
|
|
1264
|
+
closed.push(`${id} 是 ${mainline.status}`);
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
served[id] = action.serves.find((ref) => ref.startsWith(`${id}/`));
|
|
1268
|
+
for (const grant of mainline.grants ?? []) grants.push({
|
|
1269
|
+
mainline: id,
|
|
1270
|
+
grant,
|
|
1271
|
+
ref: `${id}#${grant.id}`
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
if (Object.keys(served).length === 0) return {
|
|
1275
|
+
ok: false,
|
|
1276
|
+
reason: `${action.id} 服務的主脈絡已不在進行中(${closed.join("、")}),授權不再生效`
|
|
1277
|
+
};
|
|
1278
|
+
return {
|
|
1279
|
+
ok: true,
|
|
1280
|
+
scope: {
|
|
1281
|
+
action,
|
|
1282
|
+
grants,
|
|
1283
|
+
served
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
/** Every request must be covered by some grant in scope; the first one that is not is named in the reason. */
|
|
1288
|
+
function matchGrants(scope, requests) {
|
|
1289
|
+
const matches = [];
|
|
1290
|
+
for (const request of requests) {
|
|
1291
|
+
const grant = scope.grants.find((g) => {
|
|
1292
|
+
const parsed = parseGrantTarget(g.grant.action, g.grant.target);
|
|
1293
|
+
return parsed.ok && grantCovers(parsed.target, request);
|
|
1294
|
+
});
|
|
1295
|
+
if (!grant) return {
|
|
1296
|
+
ok: false,
|
|
1297
|
+
reason: `${Object.keys(scope.served).join("、")} 沒有涵蓋 ${describeRequest(request)} 的授權`
|
|
1298
|
+
};
|
|
1299
|
+
matches.push({
|
|
1300
|
+
request,
|
|
1301
|
+
grant
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
return {
|
|
1305
|
+
ok: true,
|
|
1306
|
+
matches
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* One line per grant in effect for the session, for the briefing and the per-turn reminder, with the fixed form
|
|
1311
|
+
* the hook allows for it; empty when the session has none or they cannot be read, since a briefing must not fail
|
|
1312
|
+
* on them.
|
|
1313
|
+
*/
|
|
1314
|
+
function grantLines(root, session) {
|
|
1315
|
+
try {
|
|
1316
|
+
const result = grantScope(root, session);
|
|
1317
|
+
if (!result.ok) return [];
|
|
1318
|
+
return result.scope.grants.map((g) => {
|
|
1319
|
+
const parsed = parseGrantTarget(g.grant.action, g.grant.target);
|
|
1320
|
+
const form = parsed.ok ? grantForm(parsed.target) : void 0;
|
|
1321
|
+
return `- ${g.ref} ${g.grant.action} ${g.grant.target}${form ? `:${form}` : ""}`;
|
|
1322
|
+
});
|
|
1323
|
+
} catch {
|
|
1324
|
+
return [];
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
//#endregion
|
|
1174
1328
|
//#region ../core/dist/sessions.js
|
|
1175
1329
|
const sessionsDir = (root) => join(root, DATA_DIR, "local", "sessions");
|
|
1176
1330
|
const sessionFile = (root, id) => join(sessionsDir(root), `${id}.yaml`);
|
|
@@ -1192,7 +1346,7 @@ function loadSessions(root) {
|
|
|
1192
1346
|
const file = join(dir, name);
|
|
1193
1347
|
let data;
|
|
1194
1348
|
try {
|
|
1195
|
-
data = parse(readText(file) ?? "");
|
|
1349
|
+
data = parse$1(readText(file) ?? "");
|
|
1196
1350
|
} catch (error) {
|
|
1197
1351
|
problems.push({
|
|
1198
1352
|
file: relative(root, file),
|
|
@@ -1544,6 +1698,8 @@ function sessionBriefing(root, session, options) {
|
|
|
1544
1698
|
} else {
|
|
1545
1699
|
lines.push(doing ? `目前行動:${doing.id} ${doing.do}` : "目前沒有進行中的行動。");
|
|
1546
1700
|
if (doing) lines.push(`服務:${servedLine(root, doing)}`);
|
|
1701
|
+
const grants = grantLines(root, session);
|
|
1702
|
+
if (grants.length > 0) lines.push("目前行動服務的主脈絡預先授權了這些動作:", ...grants);
|
|
1547
1703
|
if (upcoming.length > 0) lines.push(`接下來:${upcoming.map((a) => `${a.id} ${a.do}`).join("、")}`);
|
|
1548
1704
|
const blocked = session.actions.filter((a) => a.status === "blocked");
|
|
1549
1705
|
if (blocked.length > 0) lines.push(`等外部條件:${blocked.map(waitingLine).join(";")}`);
|
|
@@ -1562,9 +1718,12 @@ function turnReminder(root, session, options) {
|
|
|
1562
1718
|
const blocked = session.actions.filter((a) => a.status === "blocked");
|
|
1563
1719
|
const head = doing ? `[mainflow] 目前行動 ${doing.id} ${doing.do},服務 ${doing.serves.join("、") || "(未指定)"}。這一輪的工作若不屬於它,先調整佇列再做。` : open.length > 0 ? `[mainflow] ${session.id} 目前沒有進行中的行動。` : blocked.length > 0 ? `[mainflow] ${session.id} 的行動在等外部條件:${blocked.map(waitingLine).join(";")}。條件出現後用 ${options.cli} action set <a編號> --status doing 繼續;要先做別的事,用 ${options.cli} action add 列出行動。` : `[mainflow] ${session.id} 的行動都已結束。繼續工作前先用 ${options.cli} action add 列出下一個行動。`;
|
|
1564
1720
|
const header = headerLine(session);
|
|
1721
|
+
const marker = header ? [`- 這一輪最後一則回覆的最後一行寫「${header}」,回覆範例等其他內容都放在它前面。有顯示 hook 時,它會換成標題與連結。`] : [];
|
|
1722
|
+
const grants = grantLines(root, session);
|
|
1565
1723
|
return [
|
|
1566
1724
|
head,
|
|
1567
|
-
...
|
|
1725
|
+
...grants.length > 0 ? ["- 目前行動服務的主脈絡預先授權了這些動作:", ...grants.map((g) => ` ${g}`)] : [],
|
|
1726
|
+
...marker,
|
|
1568
1727
|
...queueWarnings(root, session, options.cli).map((w) => `- ${w}`)
|
|
1569
1728
|
].join("\n");
|
|
1570
1729
|
}
|
|
@@ -1968,7 +2127,7 @@ function migrateHub(root, options = {}) {
|
|
|
1968
2127
|
if (!existsSync(configFile)) throw new WriteError(`no hub at ${root}; run mainflow init first`);
|
|
1969
2128
|
const rel = (path) => relative(root, path);
|
|
1970
2129
|
return withLock(root, () => {
|
|
1971
|
-
const config = parse(readFileSync(configFile, "utf8"));
|
|
2130
|
+
const config = parse$1(readFileSync(configFile, "utf8"));
|
|
1972
2131
|
const from = Number(config.formatVersion);
|
|
1973
2132
|
if (from === 2) throw new WriteError(`${rel(configFile)} is already format 2; nothing to migrate`);
|
|
1974
2133
|
if (from !== 1) throw new WriteError(`cannot migrate from format ${String(config.formatVersion)}; this CLI migrates format 1 to 2`);
|
|
@@ -1981,7 +2140,7 @@ function migrateHub(root, options = {}) {
|
|
|
1981
2140
|
for (const mainlineDir of subdirs(join(dataDir, "mainlines"))) {
|
|
1982
2141
|
const yamlFile = join(mainlineDir, "mainline.yaml");
|
|
1983
2142
|
if (!existsSync(yamlFile)) continue;
|
|
1984
|
-
const m = parse(readFileSync(yamlFile, "utf8"));
|
|
2143
|
+
const m = parse$1(readFileSync(yamlFile, "utf8"));
|
|
1985
2144
|
dropNull(m, "archivedAt");
|
|
1986
2145
|
if (isClosed("mainline", m.status) && m.archivedAt) m.closedAt = m.archivedAt;
|
|
1987
2146
|
const criteria = (m.criteria ?? []).map(migrateListItem);
|
|
@@ -1998,7 +2157,7 @@ function migrateHub(root, options = {}) {
|
|
|
1998
2157
|
for (const taskDir of subdirs(join(mainlineDir, "tasks"))) {
|
|
1999
2158
|
const taskYaml = join(taskDir, "task.yaml");
|
|
2000
2159
|
if (!existsSync(taskYaml)) continue;
|
|
2001
|
-
const t = parse(readFileSync(taskYaml, "utf8"));
|
|
2160
|
+
const t = parse$1(readFileSync(taskYaml, "utf8"));
|
|
2002
2161
|
const content = typeof t.content === "string" ? t.content.trim() : "";
|
|
2003
2162
|
drop(t, "content");
|
|
2004
2163
|
dropNull(t, "parent", "repo");
|
|
@@ -2191,4 +2350,4 @@ function openInApp(hub, target, closeAfterMs = 150) {
|
|
|
2191
2350
|
return true;
|
|
2192
2351
|
}
|
|
2193
2352
|
//#endregion
|
|
2194
|
-
export {
|
|
2353
|
+
export { reopenIssue as $, addAction as A, transcriptPath as B, setCriterionText as C, updateTask as D, supersedeDecision as E, setSessionArchived as F, endsWithMarker as G, grantScope as H, setSessionInfo as I, appendOps as J, headerLine as K, setSessionStatus as L, handoffSession as M, loadSessions as N, sessionBriefing as O, readSession as P, planIssue as Q, settleSession as R, setCriterion as S, setMainlineTitle as T, matchGrants as U, updateAction as V, decorateReply as W, createFinding as X, closeIssue as Y, createIssue as Z, createTask as _, worktreesOf as _t, openInApp as a, dependencyGraph as at, setArchived as b, syncHost as c, refIndex as ct, setArchivedMany as d, ConflictError as dt, setFindingArchived as et, acceptDecision as f, WriteError as ft, createMainline as g, findHubRoot as gt, createDecision as h, currentBranch as ht, hostName as i, loadHub as it, ensureSession as j, turnReminder as k, migrateHub as l, MAINLINE_FILE as lt, addRepo as m, DATA_DIR as mt, DEFAULT_UI_PORT as n, setIssueArchived as nt, removeHostLink as o, mainlineEdges as ot, addHub as p, readYaml as pt, mayDecorate as q, caddySites as r, HubError as rt, siteBlock as s, linksInto as st, APP_BUNDLE_ID as t, setFindingStatus as tt, ARCHIVE_KINDS as u, TASK_FILE as ut, dropChecklistItem as v, setMainlineStatus as w, setChecklistItem as x, initHub as y, startSession as z };
|
package/dist/host.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as openInApp, c as syncHost, i as hostName, n as DEFAULT_UI_PORT, o as removeHostLink, r as caddySites, s as siteBlock, t as APP_BUNDLE_ID } from "./host-
|
|
1
|
+
import { a as openInApp, c as syncHost, i as hostName, n as DEFAULT_UI_PORT, o as removeHostLink, r as caddySites, s as siteBlock, t as APP_BUNDLE_ID } from "./host-0_zkFbzM.js";
|
|
2
2
|
export { APP_BUNDLE_ID, DEFAULT_UI_PORT, caddySites, hostName, openInApp, removeHostLink, siteBlock, syncHost };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region ../schema/dist/index.d.ts
|
|
3
|
+
declare const FORMAT_VERSION = 2;
|
|
4
|
+
declare const ID_PATTERNS: {
|
|
5
|
+
readonly mainline: RegExp;
|
|
6
|
+
readonly task: RegExp;
|
|
7
|
+
readonly checklistItem: RegExp;
|
|
8
|
+
readonly criterion: RegExp;
|
|
9
|
+
readonly decision: RegExp;
|
|
10
|
+
readonly action: RegExp;
|
|
11
|
+
readonly issue: RegExp;
|
|
12
|
+
readonly finding: RegExp;
|
|
13
|
+
readonly grant: RegExp;
|
|
14
|
+
};
|
|
15
|
+
declare const CHECKLIST_REF: RegExp;
|
|
16
|
+
declare const SLUG: RegExp;
|
|
17
|
+
/** One source the survey checks: the line's label, what it holds, and how it may be left unchecked. */
|
|
18
|
+
interface SurveyLine {
|
|
19
|
+
label: string;
|
|
20
|
+
holds: string;
|
|
21
|
+
/** The word that marks the source as not checked, followed by the reason, e.g. 不適用:{理由}. Absent when the source is always checked. */
|
|
22
|
+
skip?: string;
|
|
23
|
+
/** Text a checked line must contain, e.g. the environment a spike ran in. */
|
|
24
|
+
requires?: string;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { SurveyLine as a, SLUG as i, FORMAT_VERSION as n, ID_PATTERNS as r, CHECKLIST_REF as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as syncHost,
|
|
1
|
+
import { c as syncHost, ft as WriteError, i as hostName, mt as DATA_DIR, n as DEFAULT_UI_PORT, o as removeHostLink } from "./host-0_zkFbzM.js";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -176,7 +176,7 @@ async function launchUi(root, hub, configured, options) {
|
|
|
176
176
|
}
|
|
177
177
|
let server;
|
|
178
178
|
if (!reuse) {
|
|
179
|
-
const { serveUi } = await import("./ui-
|
|
179
|
+
const { serveUi } = await import("./ui-hvirfamo.js");
|
|
180
180
|
server = await serveUi(root, choice.port);
|
|
181
181
|
writeUiRecord(root, {
|
|
182
182
|
port: choice.port,
|
package/dist/launch.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as portCandidates, c as watchHubGone, i as networkProbe, n as choosePort, o as readUiRecord, r as launchUi, s as startUiInBackground, t as PORT_SPAN } from "./launch-
|
|
1
|
+
import { a as portCandidates, c as watchHubGone, i as networkProbe, n as choosePort, o as readUiRecord, r as launchUi, s as startUiInBackground, t as PORT_SPAN } from "./launch-B8-NVG2g.js";
|
|
2
2
|
export { PORT_SPAN, choosePort, launchUi, networkProbe, portCandidates, readUiRecord, startUiInBackground, watchHubGone };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as transcriptPath, D as updateTask, F as setSessionArchived, N as loadSessions, P as readSession,
|
|
1
|
+
import { B as transcriptPath, D as updateTask, F as setSessionArchived, N as loadSessions, P as readSession, S as setCriterion, T as setMainlineTitle, a as openInApp, at as dependencyGraph, b as setArchived, ct as refIndex, d as setArchivedMany, dt as ConflictError, et as setFindingArchived, ft as WriteError, it as loadHub, mt as DATA_DIR, nt as setIssueArchived, ot as mainlineEdges, st as linksInto, u as ARCHIVE_KINDS, w as setMainlineStatus, x as setChecklistItem } from "./host-0_zkFbzM.js";
|
|
2
2
|
import { t as listProgress } from "./progress-1BfPg2zN.js";
|
|
3
|
-
import { l as CLI_VERSION } from "./launch-
|
|
3
|
+
import { l as CLI_VERSION } from "./launch-B8-NVG2g.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { closeSync, existsSync, openSync, readFileSync, readSync, statSync, watch } from "node:fs";
|
|
6
6
|
import { basename, dirname, extname, join, normalize, relative, sep } from "node:path";
|