@pmelab/gtd 61.0.0 → 62.0.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/.claude-plugin/plugin.json +1 -1
- package/README.md +9 -0
- package/dist/chunks/{testkit-C9sq0x07.mjs → testkit-XQeYCNMn.mjs} +20 -61
- package/dist/gtd.bundle.mjs +227 -80
- package/dist/gtd.core.mjs +110 -110
- package/dist/testkit/gherkin.mjs +1 -1
- package/dist/testkit.mjs +1 -1
- package/package.json +1 -1
- package/src/cli/Cli.ts +6 -1
- package/src/cli/Launch.test.ts +52 -0
- package/src/cli/Launch.ts +143 -0
- package/src/cli/Program.test.ts +1 -2
- package/src/cli/Program.ts +0 -1
- package/src/cli/index.ts +1 -0
- package/src/edge/Edge.test.ts +3 -3
- package/src/edge/Edge.ts +17 -71
- package/src/platform/PinFile.ts +61 -0
- package/src/platform/index.ts +1 -0
- package/src/replay/Trailers.test.ts +0 -37
- package/src/replay/Trailers.ts +2 -23
- package/src/step/planStart.test.ts +0 -1
- package/src/step/planStart.ts +1 -5
- package/src/twins/PinFile.test.ts +107 -0
- package/src/twins/PinFile.ts +12 -0
- package/src/twins/index.ts +1 -0
- package/src/workflow/fingerprint.ts +2 -2
- package/src/workflow/index.ts +2 -2
- package/src/workflow/load.ts +14 -1
- package/src/workflow/pin.ts +15 -7
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from 'module';
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
|
-
import { createRequire, isBuiltin } from "node:module";
|
|
4
|
+
import { createRequire, isBuiltin, registerHooks } from "node:module";
|
|
5
5
|
import * as OS from "node:os";
|
|
6
6
|
import { homedir, networkInterfaces, tmpdir } from "node:os";
|
|
7
7
|
import * as NodeChildProcess from "node:child_process";
|
|
@@ -14,7 +14,7 @@ import * as NFS from "node:fs";
|
|
|
14
14
|
import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
15
15
|
import * as Path from "node:path";
|
|
16
16
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
17
|
-
import { gzipSync } from "node:zlib";
|
|
17
|
+
import { gunzipSync, gzipSync } from "node:zlib";
|
|
18
18
|
import * as NodeUrl from "node:url";
|
|
19
19
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
20
20
|
import { stripVTControlCharacters } from "node:util";
|
|
@@ -12054,6 +12054,57 @@ const restorability = (git, headHash, tipHash) => gen(function* () {
|
|
|
12054
12054
|
};
|
|
12055
12055
|
});
|
|
12056
12056
|
//#endregion
|
|
12057
|
+
//#region src/platform/PinFile.ts
|
|
12058
|
+
const livePinFile = (cwd, path) => () => {
|
|
12059
|
+
const file = join(cwd, path);
|
|
12060
|
+
if (existsSync(file)) try {
|
|
12061
|
+
return {
|
|
12062
|
+
path: file,
|
|
12063
|
+
bytes: readFileSync(file)
|
|
12064
|
+
};
|
|
12065
|
+
} catch {
|
|
12066
|
+
return {
|
|
12067
|
+
path: file,
|
|
12068
|
+
bytes: /* @__PURE__ */ new Uint8Array()
|
|
12069
|
+
};
|
|
12070
|
+
}
|
|
12071
|
+
try {
|
|
12072
|
+
return {
|
|
12073
|
+
path: file,
|
|
12074
|
+
bytes: execFileSync("git", ["show", `HEAD:${path}`], {
|
|
12075
|
+
cwd,
|
|
12076
|
+
stdio: [
|
|
12077
|
+
"ignore",
|
|
12078
|
+
"pipe",
|
|
12079
|
+
"ignore"
|
|
12080
|
+
]
|
|
12081
|
+
})
|
|
12082
|
+
};
|
|
12083
|
+
} catch {
|
|
12084
|
+
return;
|
|
12085
|
+
}
|
|
12086
|
+
};
|
|
12087
|
+
/**
|
|
12088
|
+
* Runs a pin's module as this process's main program. Node refuses an unknown
|
|
12089
|
+
* extension, so a load hook serves the unpacked source under the pin's own
|
|
12090
|
+
* URL — `import.meta.url` stays a file in the repository.
|
|
12091
|
+
*/
|
|
12092
|
+
const runPinModule = async (path, source) => {
|
|
12093
|
+
const url = pathToFileURL(path).href;
|
|
12094
|
+
registerHooks({
|
|
12095
|
+
resolve: (specifier, context, nextResolve) => specifier === url ? {
|
|
12096
|
+
url,
|
|
12097
|
+
shortCircuit: true
|
|
12098
|
+
} : nextResolve(specifier, context),
|
|
12099
|
+
load: (requested, context, nextLoad) => requested === url ? {
|
|
12100
|
+
format: "module",
|
|
12101
|
+
source,
|
|
12102
|
+
shortCircuit: true
|
|
12103
|
+
} : nextLoad(requested, context)
|
|
12104
|
+
});
|
|
12105
|
+
await import(url);
|
|
12106
|
+
};
|
|
12107
|
+
//#endregion
|
|
12057
12108
|
//#region src/flags/index.ts
|
|
12058
12109
|
const FLAGS$1 = [];
|
|
12059
12110
|
const BOOL = {
|
|
@@ -29513,13 +29564,7 @@ const parseJson = (raw) => {
|
|
|
29513
29564
|
const TRAILER_RE = /^(Gtd-[A-Za-z-]+):[ \t]*(.*?)[ \t]*$/gm;
|
|
29514
29565
|
const COST_RE = /^([0-9]+(?:\.[0-9]+)?)(?:[ \t]+(.+))?$/;
|
|
29515
29566
|
const VAR_RE = /^([^=\s]+)=(.*)$/;
|
|
29516
|
-
const CONFIG_RE = /^([0-9a-f]{16}) (.+)$/;
|
|
29517
29567
|
const CONTROL_CHARACTER$1 = /[\x00-\x1f\x7f-\x9f\u2028\u2029]/;
|
|
29518
|
-
const encodePath = (path) => path.trim() !== path || path.startsWith("\"") || CONTROL_CHARACTER$1.test(path) ? JSON.stringify(path) : path;
|
|
29519
|
-
const decodePath = (raw) => {
|
|
29520
|
-
const path = raw.startsWith("\"") ? parseJson(raw) : raw;
|
|
29521
|
-
return typeof path === "string" && path !== "" && !CONTROL_CHARACTER$1.test(path) ? path : void 0;
|
|
29522
|
-
};
|
|
29523
29568
|
const decodeApproval = (raw) => {
|
|
29524
29569
|
const parsed = parseJson(raw);
|
|
29525
29570
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
|
|
@@ -29571,11 +29616,6 @@ const TRAILER_READERS = {
|
|
|
29571
29616
|
const kv = VAR_RE.exec(value);
|
|
29572
29617
|
if (kv !== null) into.vars[kv[1]] = kv[2];
|
|
29573
29618
|
},
|
|
29574
|
-
"Gtd-Config": (value, into) => {
|
|
29575
|
-
const entry = CONFIG_RE.exec(value);
|
|
29576
|
-
const path = entry === null ? void 0 : decodePath(entry[2]);
|
|
29577
|
-
if (path !== void 0) into.config[path] = entry[1];
|
|
29578
|
-
},
|
|
29579
29619
|
"Gtd-Review-Base": (value, into) => {
|
|
29580
29620
|
into.reviewBase ??= value.split(/\s/)[0];
|
|
29581
29621
|
},
|
|
@@ -29620,7 +29660,6 @@ const parseCommitMessage = (message) => {
|
|
|
29620
29660
|
judge: [],
|
|
29621
29661
|
marks: [],
|
|
29622
29662
|
vars: {},
|
|
29623
|
-
config: {},
|
|
29624
29663
|
cost: [],
|
|
29625
29664
|
format: void 0
|
|
29626
29665
|
};
|
|
@@ -29642,7 +29681,6 @@ const formatCommitMessage = (spec) => {
|
|
|
29642
29681
|
...trailer("Workflow", spec.workflow),
|
|
29643
29682
|
...trailer("Review-Base", spec.reviewBase),
|
|
29644
29683
|
...sortedEntries(spec.vars).map(([name, value]) => `Gtd-Var: ${name}=${value}`),
|
|
29645
|
-
...sortedEntries(spec.config).map(([path, hash]) => `Gtd-Config: ${hash} ${encodePath(path)}`),
|
|
29646
29684
|
...trailer("Cost", costValue(spec.cost)),
|
|
29647
29685
|
...(spec.judge ?? []).map((verdict) => `Gtd-Judge: ${JSON.stringify(verdict)}`),
|
|
29648
29686
|
...(spec.marks ?? []).map((m) => `Gtd-Mark: ${m.name}=${m.value}`),
|
|
@@ -30564,7 +30602,8 @@ const load = gen(function* () {
|
|
|
30564
30602
|
},
|
|
30565
30603
|
...compiled.ui !== void 0 ? { ui: compiled.ui } : {},
|
|
30566
30604
|
warnings: diagnostics.filter((d) => d.severity === "warning"),
|
|
30567
|
-
fingerprint: pinned?.fingerprint ?? configFingerprint(loaded.file.dependencyFiles, host.root, module.read ?? readFromDisk)
|
|
30605
|
+
fingerprint: pinned?.fingerprint ?? configFingerprint(loaded.file.dependencyFiles, host.root, module.read ?? readFromDisk),
|
|
30606
|
+
drift: pinned === void 0 ? [] : changedConfigFiles(pinned.fingerprint, configFingerprint(Object.keys(pinned.fingerprint).map((file) => resolve(host.root, file)), host.root, readFromDisk))
|
|
30568
30607
|
};
|
|
30569
30608
|
});
|
|
30570
30609
|
const readFromDisk = (path) => {
|
|
@@ -31218,8 +31257,6 @@ const knownModes = (def) => Object.keys(def.modes);
|
|
|
31218
31257
|
//#endregion
|
|
31219
31258
|
//#region src/workflow/pin.ts
|
|
31220
31259
|
init_dist$1();
|
|
31221
|
-
/** Bumped when a launcher could no longer run an older pin the same way. */
|
|
31222
|
-
const PIN_FORMAT = 1;
|
|
31223
31260
|
/**
|
|
31224
31261
|
* The engine a pin carries, as ES module source. Live, the `gtd.core.mjs` the
|
|
31225
31262
|
* running gtd ships beside its own bundle.
|
|
@@ -31245,8 +31282,26 @@ const pin = (module, root, version) => gen(function* () {
|
|
|
31245
31282
|
try: () => pinnedWorkflowSource(module, root, version),
|
|
31246
31283
|
catch: (e) => new GtdError(`gtd bundle: ${module.filepath}: ${e instanceof Error ? e.message : String(e)}`)
|
|
31247
31284
|
})) + core.replace(/^#!.*\n/, "");
|
|
31248
|
-
return Buffer.concat([Buffer.from(`gtdpin
|
|
31285
|
+
return Buffer.concat([Buffer.from(`gtdpin 1 gtd ${version}\n`), gzipSync(source, { level: 9 })]);
|
|
31249
31286
|
});
|
|
31287
|
+
/** A pin's header line, read without unpacking it; undefined when the bytes are no pin. */
|
|
31288
|
+
const pinHeader = (bytes) => {
|
|
31289
|
+
const end = bytes.indexOf(10);
|
|
31290
|
+
const header = end < 0 ? null : /^gtdpin (\d+) gtd (\S+)$/.exec(Buffer.from(bytes.subarray(0, end)).toString());
|
|
31291
|
+
return header === null ? void 0 : {
|
|
31292
|
+
format: Number(header[1]),
|
|
31293
|
+
version: header[2]
|
|
31294
|
+
};
|
|
31295
|
+
};
|
|
31296
|
+
/** A pin's header and module source. */
|
|
31297
|
+
const readPin = (bytes) => {
|
|
31298
|
+
const header = pinHeader(bytes);
|
|
31299
|
+
if (header === void 0) throw new Error("not a gtd pin");
|
|
31300
|
+
return {
|
|
31301
|
+
...header,
|
|
31302
|
+
source: gunzipSync(bytes.subarray(bytes.indexOf(10) + 1)).toString("utf8")
|
|
31303
|
+
};
|
|
31304
|
+
};
|
|
31250
31305
|
//#endregion
|
|
31251
31306
|
//#region src/emit/GitScript.ts
|
|
31252
31307
|
const shellQuote$1 = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
@@ -31876,8 +31931,7 @@ const checkOverrides = (commandLabel, varOverrides, declaredNames, envNames) =>
|
|
|
31876
31931
|
* `gtd start <name>`: start a brand NEW process on a workflow, writing an
|
|
31877
31932
|
* opening commit that names the workflow's first step and carries a
|
|
31878
31933
|
* `Gtd-Workflow:` trailer, every process setting as a `Gtd-Var:` trailer, plus
|
|
31879
|
-
* a `Gtd-Review-Base:` trailer when the workflow fixes the process's diff base
|
|
31880
|
-
* and a `Gtd-Config:` trailer per config file.
|
|
31934
|
+
* and a `Gtd-Review-Base:` trailer when the workflow fixes the process's diff base.
|
|
31881
31935
|
* All validation is a REFUSAL, not an Effect failure.
|
|
31882
31936
|
*/
|
|
31883
31937
|
const planStart = (current, actor, start) => gen(function* () {
|
|
@@ -31915,8 +31969,7 @@ const planStart = (current, actor, start) => gen(function* () {
|
|
|
31915
31969
|
to: firstStep,
|
|
31916
31970
|
workflow: name,
|
|
31917
31971
|
...base !== void 0 ? { reviewBase: base } : {},
|
|
31918
|
-
vars
|
|
31919
|
-
config: start.config
|
|
31972
|
+
vars
|
|
31920
31973
|
})
|
|
31921
31974
|
}
|
|
31922
31975
|
}, {
|
|
@@ -32025,15 +32078,6 @@ const runOf = (history, location, closingHash = void 0) => {
|
|
|
32025
32078
|
const fault = historyFormatFault(history, location);
|
|
32026
32079
|
return fault === void 0 ? succeed$1(buildRun(history, location, closingHash)) : fail$8(new Error(fault));
|
|
32027
32080
|
};
|
|
32028
|
-
const pinnedConfigOf = (history) => {
|
|
32029
|
-
for (let i = history.length - 1; i >= 0; i--) {
|
|
32030
|
-
const files = parseCommitMessage(history[i].message).config;
|
|
32031
|
-
if (Object.keys(files).length > 0) return {
|
|
32032
|
-
commit: history[i].hash,
|
|
32033
|
-
files
|
|
32034
|
-
};
|
|
32035
|
-
}
|
|
32036
|
-
};
|
|
32037
32081
|
const approvalEntryOf = (hash, message) => message.approved === void 0 ? [] : [{
|
|
32038
32082
|
step: formatStepId(message.approved.step),
|
|
32039
32083
|
name: message.approved.name,
|
|
@@ -32061,7 +32105,6 @@ const buildRun = (history, location, closingHash) => {
|
|
|
32061
32105
|
marks: parsed.flatMap((m) => m.marks),
|
|
32062
32106
|
approvals: processCommits.flatMap((c, i) => approvalEntryOf(c.hash, parsed[i])),
|
|
32063
32107
|
pinnedVars: { ...first?.vars },
|
|
32064
|
-
pinnedConfig: pinnedConfigOf(history.slice(Math.max(location.baseIndex, 0))),
|
|
32065
32108
|
headTurn: headTurnOf(head),
|
|
32066
32109
|
closingHash,
|
|
32067
32110
|
episode: {
|
|
@@ -32151,18 +32194,6 @@ const findBoundaryBase = (git, def, head) => gen(function* () {
|
|
|
32151
32194
|
});
|
|
32152
32195
|
const historyUpTo = (git, def, head) => flatMap(findBoundaryBase(git, def, head), ({ base, head: resolvedHead }) => git.commitHistory(base, resolvedHead));
|
|
32153
32196
|
const computeProcessRun = (git, def, head) => flatMap(historyUpTo(git, def, head), (history) => runOf(history, locateEpisode(def, history)));
|
|
32154
|
-
const changedSinceStart = (pinned, current, workspace) => {
|
|
32155
|
-
if (pinned === void 0) return [];
|
|
32156
|
-
return changedConfigFiles(pinned.files, current).filter((path) => {
|
|
32157
|
-
const committed = workspace.readCommittedSync(path, pinned.commit);
|
|
32158
|
-
return current[path] === void 0 || committed === void 0 || contentHash(committed) !== current[path];
|
|
32159
|
-
});
|
|
32160
|
-
};
|
|
32161
|
-
const warnConfigChanges = (run, current, workspace) => gen(function* () {
|
|
32162
|
-
const changed = changedSinceStart(run.pinnedConfig, current, workspace);
|
|
32163
|
-
if (changed.length === 0) return;
|
|
32164
|
-
yield* (yield* Narrator).warn(`gtd: warning: the config changed since this process started (${changed.join(", ")}) — the rest of the process replays under the changed config`);
|
|
32165
|
-
});
|
|
32166
32197
|
/** The run alone, never replaying — `gtd abandon` must work even when replay would refuse, short of a history it cannot read. */
|
|
32167
32198
|
const currentRun = gen(function* () {
|
|
32168
32199
|
const git = yield* GitService;
|
|
@@ -32478,8 +32509,7 @@ const restAt = (ref, startOverrides = {}) => gen(function* () {
|
|
|
32478
32509
|
status: normalizeStatus(e.status),
|
|
32479
32510
|
path: e.path
|
|
32480
32511
|
})) : [];
|
|
32481
|
-
|
|
32482
|
-
if (ref === void 0) yield* warnConfigChanges(run, configNow, workspace);
|
|
32512
|
+
if (ref === void 0 && config.drift.length > 0) yield* (yield* Narrator).warn(`gtd: notice: the live config differs from the pinned one (${config.drift.join(", ")}); \`gtd repin\` to switch`);
|
|
32483
32513
|
return {
|
|
32484
32514
|
def,
|
|
32485
32515
|
workflowName: resolved.name,
|
|
@@ -32493,7 +32523,6 @@ const restAt = (ref, startOverrides = {}) => gen(function* () {
|
|
|
32493
32523
|
run,
|
|
32494
32524
|
vars,
|
|
32495
32525
|
env,
|
|
32496
|
-
config: configNow,
|
|
32497
32526
|
changes,
|
|
32498
32527
|
memory: memory.key,
|
|
32499
32528
|
memoryResumed: memory.resumed,
|
|
@@ -32757,10 +32786,7 @@ const pinRefusal = (pin) => ({
|
|
|
32757
32786
|
kind: "refusal",
|
|
32758
32787
|
message: pin === "add" ? `gtd land: ${PIN_PATH} is missing — run the pin beat's script (\`gtd next --json=content\`); if its \`gtd bundle\` fails, fix what it reports, or run \`gtd abandon\`` : `gtd land: ${PIN_PATH} is still there — run the unpin beat's script (\`gtd next --json=content\`), then land`
|
|
32759
32788
|
});
|
|
32760
|
-
const startTrailers = (rest, starts) => starts ? {
|
|
32761
|
-
vars: rest.vars,
|
|
32762
|
-
config: rest.config
|
|
32763
|
-
} : {};
|
|
32789
|
+
const startTrailers = (rest, starts) => starts ? { vars: rest.vars } : {};
|
|
32764
32790
|
const outcomeMarks = (outcome) => outcome.kind === "rest" || outcome.kind === "ended" ? outcome.marks : [];
|
|
32765
32791
|
/**
|
|
32766
32792
|
* What landing the pending turn at `rest` does — a pure decision from a
|
|
@@ -32831,16 +32857,20 @@ const summaryFor = (run) => gen(function* () {
|
|
|
32831
32857
|
if (summary === void 0 || run.trace.length === 0) return { prompt: void 0 };
|
|
32832
32858
|
return { prompt: summary(summaryInput(run, settingsFor(resolved, run.pinnedVars, host.env, {}, {}))) };
|
|
32833
32859
|
});
|
|
32834
|
-
/**
|
|
32835
|
-
|
|
32836
|
-
|
|
32860
|
+
/**
|
|
32861
|
+
* Repository-relative paths of today's config files; one outside the
|
|
32862
|
+
* repository cannot be read at a ref, so it is left out. A file only the old
|
|
32863
|
+
* config read needs no check: whichever file imported it differs too.
|
|
32864
|
+
*/
|
|
32865
|
+
const inRepoConfigPaths = (root, files) => {
|
|
32866
|
+
const paths = /* @__PURE__ */ new Set();
|
|
32837
32867
|
for (const file of files) paths.add(relative(root, resolve(root, file)).split(sep).join("/"));
|
|
32838
32868
|
return [...paths].filter((p) => p !== "" && !p.startsWith("..") && !isAbsolute(p)).sort();
|
|
32839
32869
|
};
|
|
32840
32870
|
const configRefusal = (command, tip, paths, reason = "A history ref replays under today's config, so it is unreadable after the config changes") => /* @__PURE__ */ new Error(`${command}: refused — config differs at ${tip.slice(0, 7)}: ${paths.join(", ")}. ${reason}`);
|
|
32841
|
-
const differingConfigPaths = (git, workspace, root, config,
|
|
32871
|
+
const differingConfigPaths = (git, workspace, root, config, hash) => gen(function* () {
|
|
32842
32872
|
const differing = [];
|
|
32843
|
-
for (const path of inRepoConfigPaths(root, Object.keys(config.fingerprint)
|
|
32873
|
+
for (const path of inRepoConfigPaths(root, Object.keys(config.fingerprint))) if ((yield* orElseSucceed(git.readFileAtRef(hash, path), () => void 0)) !== workspace.readSync(path)) differing.push(path);
|
|
32844
32874
|
return differing;
|
|
32845
32875
|
});
|
|
32846
32876
|
const notClosedError = (hash, outcome) => outcome.kind === "rest" ? /* @__PURE__ */ new Error(`gtd history: ${hash.slice(0, 7)} does not close a process under today's config`) : replayError(outcome) ?? /* @__PURE__ */ new Error("gtd history: replay failed");
|
|
@@ -32897,7 +32927,7 @@ const replayFinishedProcess = (config, run, hash, how) => gen(function* () {
|
|
|
32897
32927
|
const recorded = parseCommitMessage(run.episode.commits.find((c) => c.hash === hash)?.message ?? "").version;
|
|
32898
32928
|
const versionWarning = versionWarningFor(recorded);
|
|
32899
32929
|
const withWarning = (err) => versionWarning === void 0 ? err : /* @__PURE__ */ new Error(`${err.message}\n${versionWarning}`);
|
|
32900
|
-
const differing = yield* differingConfigPaths(git, workspace, host.root, config,
|
|
32930
|
+
const differing = yield* differingConfigPaths(git, workspace, host.root, config, hash);
|
|
32901
32931
|
if (differing.length > 0) return yield* fail$8(withWarning(configRefusal(how.command, hash, differing, how.configReason)));
|
|
32902
32932
|
const { setup } = yield* setupFor(config, run, workspace, host);
|
|
32903
32933
|
const outcome = yield* promise(() => replayFor(setup));
|
|
@@ -33868,8 +33898,7 @@ const startWorkflow = (workflow, varOverrides, json, out, commandLabel) => gen(f
|
|
|
33868
33898
|
workflow: resolved,
|
|
33869
33899
|
first: started,
|
|
33870
33900
|
commandLabel,
|
|
33871
|
-
vars: varOverrides
|
|
33872
|
-
config: rest.config
|
|
33901
|
+
vars: varOverrides
|
|
33873
33902
|
});
|
|
33874
33903
|
if (plan.kind === "refusal") return yield* fail$8(new Error(plan.message));
|
|
33875
33904
|
yield* writeScript(json, out, listingCommitted(landingScript(ScriptSurface.render(plan.steps)), rest.changes));
|
|
@@ -34872,6 +34901,7 @@ const flagHeader = (row) => {
|
|
|
34872
34901
|
};
|
|
34873
34902
|
const GLOBAL_OPTIONS = [
|
|
34874
34903
|
["-v, --verbose", "Narrate on stderr what gtd resolved"],
|
|
34904
|
+
["--live", "Run this gtd, not the process's pin; it may misread the process"],
|
|
34875
34905
|
["-h, --help", "Print help; gtd <command> --help for one command"],
|
|
34876
34906
|
["-V, --version", "Print the version"],
|
|
34877
34907
|
["--", "End the options: every word after it is an argument"]
|
|
@@ -34883,7 +34913,7 @@ const EXTRA_TOPICS = [[
|
|
|
34883
34913
|
], [
|
|
34884
34914
|
"version",
|
|
34885
34915
|
"Print the version",
|
|
34886
|
-
"Print gtd's version."
|
|
34916
|
+
"Print gtd's version, and the version of a pinned process's gtd."
|
|
34887
34917
|
]];
|
|
34888
34918
|
const EXAMPLES = ` $ gtd start list what can start
|
|
34889
34919
|
$ gtd start <name> start a process
|
|
@@ -35381,6 +35411,108 @@ const runCli = (argv, io) => {
|
|
|
35381
35411
|
}), provide(io.layers(plan.verbose)), sandbox, catch_((cause) => hasInterruptsOnly(cause) ? failCause$1(cause) : report(io, plan.json.kind !== "off")(cause)));
|
|
35382
35412
|
};
|
|
35383
35413
|
//#endregion
|
|
35414
|
+
//#region src/cli/Launch.ts
|
|
35415
|
+
/** What the core a pin carries lacks, or what must read the live state: these never hand over. */
|
|
35416
|
+
const LIVE_KINDS = /* @__PURE__ */ new Set([
|
|
35417
|
+
"ui",
|
|
35418
|
+
"lsp",
|
|
35419
|
+
"guide",
|
|
35420
|
+
"bundle",
|
|
35421
|
+
"historyList",
|
|
35422
|
+
"historyShow",
|
|
35423
|
+
"historyMetrics",
|
|
35424
|
+
"historyJudges",
|
|
35425
|
+
"historyFetch"
|
|
35426
|
+
]);
|
|
35427
|
+
const LIVE_FLAG = "--live";
|
|
35428
|
+
const optionWords = (argv) => {
|
|
35429
|
+
const end = argv.indexOf("--", 2);
|
|
35430
|
+
return argv.slice(2, end < 0 ? void 0 : end);
|
|
35431
|
+
};
|
|
35432
|
+
const withoutLiveFlag = (argv) => {
|
|
35433
|
+
const end = argv.indexOf("--", 2);
|
|
35434
|
+
return argv.filter((word, i) => word !== LIVE_FLAG || i < 2 || end >= 0 && i > end);
|
|
35435
|
+
};
|
|
35436
|
+
/**
|
|
35437
|
+
* Whether this gtd runs the command or hands it to the process's pin. A pin
|
|
35438
|
+
* this gtd cannot run is refused, never guessed at; a usage error the live
|
|
35439
|
+
* parser finds is still the pin's to judge, since its engine may read
|
|
35440
|
+
* another CLI.
|
|
35441
|
+
*/
|
|
35442
|
+
const launchFor = (argv, pinFile) => {
|
|
35443
|
+
if (globalThis[PIN_KEY] !== void 0) return {
|
|
35444
|
+
kind: "live",
|
|
35445
|
+
argv
|
|
35446
|
+
};
|
|
35447
|
+
const live = optionWords(argv).includes(LIVE_FLAG);
|
|
35448
|
+
const rest = withoutLiveFlag(argv);
|
|
35449
|
+
if (live) return {
|
|
35450
|
+
kind: "live",
|
|
35451
|
+
argv: rest
|
|
35452
|
+
};
|
|
35453
|
+
const plan = parseArgv(rest);
|
|
35454
|
+
const version = plan.kind === "output" && plan.stdout === `${GTD_VERSION}\n`;
|
|
35455
|
+
if (plan.kind === "output" && !version) return {
|
|
35456
|
+
kind: "live",
|
|
35457
|
+
argv: rest
|
|
35458
|
+
};
|
|
35459
|
+
if (plan.kind === "command" && LIVE_KINDS.has(plan.command.kind)) return {
|
|
35460
|
+
kind: "live",
|
|
35461
|
+
argv: rest
|
|
35462
|
+
};
|
|
35463
|
+
const found = pinFile();
|
|
35464
|
+
if (found === void 0) return {
|
|
35465
|
+
kind: "live",
|
|
35466
|
+
argv: rest
|
|
35467
|
+
};
|
|
35468
|
+
const header = pinHeader(found.bytes);
|
|
35469
|
+
if (version) return {
|
|
35470
|
+
kind: "output",
|
|
35471
|
+
stdout: header === void 0 ? plan.stdout : `${GTD_VERSION} (this process is pinned to gtd ${header.version})\n`
|
|
35472
|
+
};
|
|
35473
|
+
if (header === void 0 || header.format !== 1) {
|
|
35474
|
+
const what = header === void 0 ? "is no pin this gtd can read" : `is pin format ${header.format}, made by gtd ${header.version}`;
|
|
35475
|
+
return {
|
|
35476
|
+
kind: "refuse",
|
|
35477
|
+
message: `gtd: ${found.path} ${what}; gtd ${GTD_VERSION} runs pin format 1 — upgrade gtd (\`gtd --live\` runs this gtd instead, and may misread the process)`
|
|
35478
|
+
};
|
|
35479
|
+
}
|
|
35480
|
+
return {
|
|
35481
|
+
kind: "pin",
|
|
35482
|
+
argv: rest,
|
|
35483
|
+
path: found.path,
|
|
35484
|
+
version: header.version,
|
|
35485
|
+
source: () => readPin(found.bytes).source
|
|
35486
|
+
};
|
|
35487
|
+
};
|
|
35488
|
+
const isJsonFlag = (word) => word === "--json" || word.startsWith("--json=");
|
|
35489
|
+
const refusalText = (argv, message) => (optionWords(argv).some(isJsonFlag) ? `${JSON.stringify({
|
|
35490
|
+
state: "error",
|
|
35491
|
+
prompt: message
|
|
35492
|
+
})}\n` : "") + `${message}\n`;
|
|
35493
|
+
const runPin = async (launch, launcher) => {
|
|
35494
|
+
const words = optionWords(launch.argv);
|
|
35495
|
+
if (words.includes("--verbose") || words.includes("-v")) launcher.stderr(`launcher: running the pin ${launch.path} (gtd ${launch.version})\n`);
|
|
35496
|
+
try {
|
|
35497
|
+
await launcher.pin(launch);
|
|
35498
|
+
} catch (error) {
|
|
35499
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
35500
|
+
launcher.stderr(`gtd: could not run the pin ${launch.path}: ${reason}\n`);
|
|
35501
|
+
launcher.exit(1);
|
|
35502
|
+
}
|
|
35503
|
+
};
|
|
35504
|
+
const runLauncher = async (argv, pinFile, launcher) => {
|
|
35505
|
+
const launch = launchFor(argv, pinFile);
|
|
35506
|
+
switch (launch.kind) {
|
|
35507
|
+
case "live": return launcher.live(launch.argv);
|
|
35508
|
+
case "output": return launcher.stdout(launch.stdout);
|
|
35509
|
+
case "refuse":
|
|
35510
|
+
launcher.stderr(refusalText(argv, launch.message));
|
|
35511
|
+
return launcher.exit(1);
|
|
35512
|
+
case "pin": return runPin(launch, launcher);
|
|
35513
|
+
}
|
|
35514
|
+
};
|
|
35515
|
+
//#endregion
|
|
35384
35516
|
//#region node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
|
|
35385
35517
|
/**
|
|
35386
35518
|
* Ensures there are no duplicate keys when building a procedure.
|
|
@@ -51407,25 +51539,40 @@ const liveToolCommands = effect(ToolCommands, gen(function* () {
|
|
|
51407
51539
|
//#endregion
|
|
51408
51540
|
//#region src/main.ts
|
|
51409
51541
|
init_dist$1();
|
|
51410
|
-
|
|
51411
|
-
|
|
51412
|
-
|
|
51413
|
-
|
|
51414
|
-
|
|
51415
|
-
|
|
51416
|
-
|
|
51417
|
-
|
|
51418
|
-
|
|
51419
|
-
|
|
51542
|
+
const runLive = (argv) => {
|
|
51543
|
+
let deathSignal;
|
|
51544
|
+
process.once("SIGINT", () => {
|
|
51545
|
+
deathSignal = "SIGINT";
|
|
51546
|
+
});
|
|
51547
|
+
process.once("SIGTERM", () => {
|
|
51548
|
+
deathSignal ??= "SIGTERM";
|
|
51549
|
+
});
|
|
51550
|
+
process.once("SIGHUP", () => {
|
|
51551
|
+
deathSignal = "SIGHUP";
|
|
51552
|
+
process.kill(process.pid, "SIGTERM");
|
|
51553
|
+
});
|
|
51554
|
+
runMain(runCli(argv, nodeCliIo(liveToolCommands)), { teardown: (exit, onExit) => {
|
|
51555
|
+
if (deathSignal === void 0) {
|
|
51556
|
+
defaultTeardown(exit, onExit);
|
|
51557
|
+
return;
|
|
51558
|
+
}
|
|
51559
|
+
const signal = deathSignal;
|
|
51560
|
+
process.removeAllListeners(signal);
|
|
51561
|
+
process.kill(process.pid, signal);
|
|
51562
|
+
} });
|
|
51563
|
+
};
|
|
51564
|
+
await runLauncher(process.argv, livePinFile(process.cwd(), PIN_PATH), {
|
|
51565
|
+
stdout: (chunk) => {
|
|
51566
|
+
process.stdout.write(chunk);
|
|
51567
|
+
},
|
|
51568
|
+
stderr: (chunk) => {
|
|
51569
|
+
process.stderr.write(chunk);
|
|
51570
|
+
},
|
|
51571
|
+
exit: (code) => {
|
|
51572
|
+
process.exitCode = code;
|
|
51573
|
+
},
|
|
51574
|
+
live: runLive,
|
|
51575
|
+
pin: (launch) => runPinModule(launch.path, launch.source())
|
|
51420
51576
|
});
|
|
51421
|
-
runMain(runCli(process.argv, nodeCliIo(liveToolCommands)), { teardown: (exit, onExit) => {
|
|
51422
|
-
if (deathSignal === void 0) {
|
|
51423
|
-
defaultTeardown(exit, onExit);
|
|
51424
|
-
return;
|
|
51425
|
-
}
|
|
51426
|
-
const signal = deathSignal;
|
|
51427
|
-
process.removeAllListeners(signal);
|
|
51428
|
-
process.kill(process.pid, signal);
|
|
51429
|
-
} });
|
|
51430
51577
|
//#endregion
|
|
51431
51578
|
export {};
|