@krapht/ork 1.0.0-alpha.15 → 1.0.0-alpha.16
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/README.md +10 -4
- package/dist/{__build_info__-Bsb1kjgF.mjs → __build_info__-DcRdK0Du.mjs} +25 -6
- package/dist/apply-Mb0fNpCX.mjs +17 -0
- package/dist/{attach-CPespxlQ.mjs → attach-7lB5_jpr.mjs} +5 -5
- package/dist/{attach-BHO3X3cf.mjs → attach-B-FeE1dJ.mjs} +46 -8
- package/dist/bin.mjs +238 -369
- package/dist/{brief-za0ozN_E.mjs → brief-BvMtIFio.mjs} +4 -4
- package/dist/{builtin-files-2bHf76x-.mjs → builtin-files-BRSOObAv.mjs} +1 -1
- package/dist/command-tree-BkSYWmYJ.mjs +63 -0
- package/dist/{completion-CQ2UYKuJ.mjs → completion-Cgb2qPPh.mjs} +45 -6
- package/dist/{context-BNqDw9z1.mjs → context-BN9A2Nnu.mjs} +3 -3
- package/dist/{find-BYLlszqj.mjs → find-mLYsR0uC.mjs} +2 -2
- package/dist/flags-CdgIH1L6.mjs +230 -0
- package/dist/{follow-ups-B4GJ3Vzw.mjs → follow-ups-DxCsOby1.mjs} +59 -24
- package/dist/{format-C8MsFj8_.mjs → format-hiDvtNGM.mjs} +17 -4
- package/dist/{help-groups-CQ98mLjF.mjs → help-groups-hB6kY34d.mjs} +1 -63
- package/dist/{in-a-run-Bp0k0J09.mjs → in-a-run-a447hxq8.mjs} +1 -1
- package/dist/{install-DWtXTq4y.mjs → install-23g_1ngs.mjs} +1 -1
- package/dist/{limits-B1qzS4cX.mjs → limits-C_Xz_t3C.mjs} +1 -1
- package/dist/{mcp-BOrVkyhN.mjs → mcp-CWng9I9n.mjs} +6 -6
- package/dist/{once-C1fL3GVo.mjs → once-lvwcWfVf.mjs} +3 -3
- package/dist/{pause-DOMK-R8V.mjs → pause-Cy11KrXK.mjs} +3 -3
- package/dist/{post-BzA6Qobq.mjs → post-C9soCx7i.mjs} +5 -3
- package/dist/print-BaWiWf4v.mjs +19 -0
- package/dist/project-records-BRiyQzUo.mjs +230 -0
- package/dist/{relay-OWuu4fib.mjs → relay-C0M1TWMB.mjs} +1 -1
- package/dist/{run--4-1xAF2.mjs → run-B-j3Qxqc.mjs} +26 -13
- package/dist/{run-CiPsW9Kf.mjs → run-D_u9V_Ve.mjs} +1 -1
- package/dist/{send-CnNNW-ot.mjs → send-qBxj0JbJ.mjs} +2 -2
- package/dist/{src-B9zWIVqo.mjs → src-CXBmaGwS.mjs} +93 -72
- package/dist/{src-DcrhgipG.mjs → src-DHDQ0itC.mjs} +91 -42
- package/dist/{src-Dr_fTSu-.mjs → src-DN-RPsil.mjs} +781 -502
- package/dist/{src-DQKz2eOH.mjs → src-nXLIwDrt.mjs} +9 -12
- package/dist/{store-oKJ-cCf3.mjs → store-Dyr1mP8K.mjs} +1 -1
- package/dist/ui/assets/app-BPSCxb_l.css +1 -0
- package/dist/ui/assets/{app-Drp8Dm9y.js → app-CnNRowFn.js} +40 -40
- package/dist/ui/assets/{index-BtwkftKe.js → index-CVzwYlz3.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/dist/{ui-CzKlsCnm.mjs → ui-DLrSt5ny.mjs} +3 -3
- package/dist/{usage-DHGNk2JL.mjs → usage-CxmpYYO4.mjs} +61 -107
- package/dist/{validate-Bs_gg22g.mjs → validate-BVrT43GO.mjs} +35 -8
- package/dist/{watch-CCCfw3n7.mjs → watch-mkLm4t9D.mjs} +5 -5
- package/dist/{workflows-CW28ZU-z.mjs → workflows-Bvl2Fquu.mjs} +2 -2
- package/dist/{worktrees-CyE8aF6j.mjs → worktrees-DOOCoS2w.mjs} +49 -20
- package/package.json +8 -4
- package/dist/ui/assets/app-Bdc6OBeZ.css +0 -1
|
@@ -113,68 +113,6 @@ complete -c ork -f -a '(__ork_complete)'
|
|
|
113
113
|
};
|
|
114
114
|
/** The shells there is a script for. */
|
|
115
115
|
const SHELLS = Object.keys(SHELL_SCRIPTS);
|
|
116
|
-
// src/command-tree.ts
|
|
117
|
-
/** How a flag that only Ork passes to itself starts its description. */
|
|
118
|
-
const INTERNAL = "Internal:";
|
|
119
|
-
/** Whether citty was given a function that gives the value. */
|
|
120
|
-
const isThunk = (value) => typeof value === "function";
|
|
121
|
-
/** A value citty lets be given as is, as a promise, or as a function. */
|
|
122
|
-
const resolved = (value) => Promise.resolve(isThunk(value) ? value() : value);
|
|
123
|
-
/** `args` without the flags only Ork passes to itself. */
|
|
124
|
-
const publicArgs = (args) => Object.fromEntries(Object.entries(args).filter(([, def]) => !(def.description ?? "").startsWith(INTERNAL)));
|
|
125
|
-
/** A command's flags and positionals, which citty lets be given lazily. */
|
|
126
|
-
const argsOf = (cmd) => cmd.args === void 0 ? Promise.resolve({}) : resolved(cmd.args);
|
|
127
|
-
const listOf = (value) => value === void 0 ? [] : [value].flat();
|
|
128
|
-
const flagOf = (name, def) => ({
|
|
129
|
-
name,
|
|
130
|
-
description: def.description ?? "",
|
|
131
|
-
takesValue: def.type === "string" || def.type === "enum",
|
|
132
|
-
aliases: "alias" in def ? listOf(def.alias) : [],
|
|
133
|
-
options: def.type === "enum" ? def.options ?? [] : [],
|
|
134
|
-
negatable: def.type === "boolean" && def.default === true
|
|
135
|
-
});
|
|
136
|
-
/** A command's public flags and positionals, in the order it defines them. */
|
|
137
|
-
const argInfoOf = async (cmd) => {
|
|
138
|
-
const entries = Object.entries(publicArgs(await argsOf(cmd)));
|
|
139
|
-
return {
|
|
140
|
-
flags: entries.filter(([, def]) => def.type !== "positional").map(([name, def]) => flagOf(name, def)),
|
|
141
|
-
positionals: entries.filter(([, def]) => def.type === "positional").map(([name, def]) => ({
|
|
142
|
-
name,
|
|
143
|
-
description: def.description ?? ""
|
|
144
|
-
}))
|
|
145
|
-
};
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* A command's subcommands, in order, loaded ones resolved. A name whose
|
|
149
|
-
* definition is one listed before it (`wt`, `worktrees`'s) is an alias of that
|
|
150
|
-
* one, not an entry of its own.
|
|
151
|
-
*/
|
|
152
|
-
const subcommandsOf = async (cmd) => {
|
|
153
|
-
const subs = cmd.subCommands === void 0 ? {} : await resolved(cmd.subCommands);
|
|
154
|
-
const loaded = await Promise.all(Object.entries(subs).map(async ([name, sub]) => {
|
|
155
|
-
const def = await resolved(sub);
|
|
156
|
-
return {
|
|
157
|
-
name,
|
|
158
|
-
def,
|
|
159
|
-
meta: def.meta === void 0 ? {} : await resolved(def.meta)
|
|
160
|
-
};
|
|
161
|
-
}));
|
|
162
|
-
const entries = [];
|
|
163
|
-
for (const { name, def, meta } of loaded) {
|
|
164
|
-
const same = entries.find((entry) => entry.def === def);
|
|
165
|
-
if (same === void 0) entries.push({
|
|
166
|
-
name,
|
|
167
|
-
aliases: listOf(meta.alias),
|
|
168
|
-
description: meta.description ?? "",
|
|
169
|
-
hidden: meta.hidden === true,
|
|
170
|
-
def
|
|
171
|
-
});
|
|
172
|
-
else same.aliases.push(name);
|
|
173
|
-
}
|
|
174
|
-
return entries;
|
|
175
|
-
};
|
|
176
|
-
/** The subcommand `name` (or one of its aliases) of `entries`. */
|
|
177
|
-
const findEntry = (entries, name) => entries.find((entry) => entry.name === name || entry.aliases.includes(name));
|
|
178
116
|
// src/help-groups.ts
|
|
179
117
|
const HELP_GROUPS = [
|
|
180
118
|
{
|
|
@@ -373,4 +311,4 @@ const groupedEntries = (entries) => {
|
|
|
373
311
|
entries: other
|
|
374
312
|
}].filter((group) => group.entries.length > 0);
|
|
375
313
|
};
|
|
376
|
-
export {
|
|
314
|
+
export { SHELL_SCRIPTS as a, SHELLS as i, groupedEntries as n, COMPLETE_COMMAND as r, groupOf as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gr as writePlainFile, Hr as estimateTokens, Nr as placeFiles, Pr as placeFor, Ur as guardedBase, Vr as LESSON_CAP_TOKENS, Wr as plainPathInside, Xn as FEEDBACK_KINDS, Zn as FEEDBACK_SEVERITIES, cr as targetOf, or as fingerprint, rr as publishPost, vr as maskSecrets, zr as inside } from "./src-DN-RPsil.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as capsHere, dt as NOT_STARTED, ft as limitsNow, pt as limitsReport } from "./src-DN-RPsil.mjs";
|
|
2
2
|
// src/run/limits.ts
|
|
3
3
|
/**
|
|
4
4
|
* @file The limits across runs that apply here (RFC-007): the user's settings
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ORK_VERSION } from "./__build_info__-
|
|
3
|
-
import { p as runMarkerIn } from "./src-
|
|
4
|
-
import { n as explainNode } from "./context-
|
|
5
|
-
import { a as openMcp, c as refused, o as tool, s as answer } from "./src-
|
|
1
|
+
import { w as isNewer } from "./src-DN-RPsil.mjs";
|
|
2
|
+
import { n as ORK_VERSION } from "./__build_info__-DcRdK0Du.mjs";
|
|
3
|
+
import { p as runMarkerIn } from "./src-DHDQ0itC.mjs";
|
|
4
|
+
import { n as explainNode } from "./context-BN9A2Nnu.mjs";
|
|
5
|
+
import { a as openMcp, c as refused, o as tool, s as answer } from "./src-nXLIwDrt.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { defineCommand } from "citty";
|
|
8
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -43,7 +43,7 @@ const orkMcpServer = (options = {}) => {
|
|
|
43
43
|
...options.script === void 0 ? {} : { script: options.script }
|
|
44
44
|
});
|
|
45
45
|
const all = [...opened.tools, explainTool(opened, options.home)];
|
|
46
|
-
const tools = options.expects !== void 0 && isNewer(options.expects, "1.0.0-alpha.
|
|
46
|
+
const tools = options.expects !== void 0 && isNewer(options.expects, "1.0.0-alpha.16") ? tooOld(all, options.expects) : all;
|
|
47
47
|
const server = new McpServer({
|
|
48
48
|
name: "ork",
|
|
49
49
|
version: ORK_VERSION
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "./src-
|
|
2
|
-
import { t as runOnce } from "./run-
|
|
1
|
+
import "./src-DN-RPsil.mjs";
|
|
2
|
+
import { t as runOnce } from "./run-D_u9V_Ve.mjs";
|
|
3
3
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
4
|
-
import { t as ago } from "./format-
|
|
4
|
+
import { t as ago } from "./format-hiDvtNGM.mjs";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { defineCommand, parseArgs } from "citty";
|
|
7
7
|
// src/commands/once.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as findRun } from "./find-
|
|
1
|
+
import { En as requestPause, L as openStore, Tn as requestContinue } from "./src-DN-RPsil.mjs";
|
|
2
|
+
import { t as findRun } from "./find-mLYsR0uC.mjs";
|
|
3
3
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
4
|
-
import { i as continueRefusal } from "./in-a-run-
|
|
4
|
+
import { i as continueRefusal } from "./in-a-run-a447hxq8.mjs";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
6
6
|
// src/commands/pause.ts
|
|
7
7
|
/**
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ir as redact } from "./src-DN-RPsil.mjs";
|
|
2
|
+
import { b as githubDraftRefusal } from "./__build_info__-DcRdK0Du.mjs";
|
|
2
3
|
// ../core/src/follow-ups/post.ts
|
|
3
4
|
/** Posts `f`'s draft as a GitHub comment once `confirmed`, and marks it done. */
|
|
4
5
|
const postFollowUpMessage = async (f, options) => {
|
|
5
6
|
const draft = f.draft;
|
|
6
|
-
|
|
7
|
+
const refused = githubDraftRefusal(f);
|
|
8
|
+
if (refused !== void 0 || draft === void 0) return {
|
|
7
9
|
ok: false,
|
|
8
|
-
error:
|
|
10
|
+
error: refused?.error ?? "it has no draft"
|
|
9
11
|
};
|
|
10
12
|
if (!options.confirmed) return {
|
|
11
13
|
ok: false,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { a as refuseIdsWithJson } from "./flags-CdgIH1L6.mjs";
|
|
2
|
+
import { c as write } from "./output-B1kwo0YU.mjs";
|
|
3
|
+
// src/list/print.ts
|
|
4
|
+
/**
|
|
5
|
+
* Prints `rows`: `--ids` their ids (`table.id`) comma-separated; `--json` the
|
|
6
|
+
* rows (or `json(rows)`); else `human(rows)`, which also says what an empty
|
|
7
|
+
* list is. `--ids` with `--json` is refused (said, exit code set).
|
|
8
|
+
*/
|
|
9
|
+
const printList = (rows, table, args, human, json = (shown) => shown) => {
|
|
10
|
+
if (refuseIdsWithJson(args)) return;
|
|
11
|
+
if (args.ids === true) {
|
|
12
|
+
const id = table.id;
|
|
13
|
+
if (id !== void 0 && rows.length > 0) write(rows.map((row) => id(row)).join(","));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (args.json === true) write(JSON.stringify(json(rows), void 0, 2));
|
|
17
|
+
else human(rows);
|
|
18
|
+
};
|
|
19
|
+
export { printList as t };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Ar as hasInRepoFiles, Br as projectRootOf, Fr as projectsHome, L as openStore, Lr as shownPath, Mr as newProjectId, Nr as placeFiles, jr as inRepoPlace } from "./src-DN-RPsil.mjs";
|
|
2
|
+
import { C as termOf, c as write, l as writeErr, s as style, w as cut } from "./output-B1kwo0YU.mjs";
|
|
3
|
+
import { n as chip } from "./chips-BqcT58qr.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { existsSync, mkdirSync, realpathSync, statSync } from "node:fs";
|
|
6
|
+
import { defineCommand } from "citty";
|
|
7
|
+
// src/project/register.ts
|
|
8
|
+
/**
|
|
9
|
+
* @file Registering projects (ADR-035): `ork register` attaches a repository
|
|
10
|
+
* from outside it, with its workflows, rules and runs in
|
|
11
|
+
* `~/.ork/projects/<id>/` and nothing written into the repository; `ork init`
|
|
12
|
+
* records an in-repo project, whose files are its `.ork/`.
|
|
13
|
+
*/
|
|
14
|
+
const ID = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
15
|
+
/** The git root of `target`'s main clone, or why there is none. */
|
|
16
|
+
const cloneOf = (target) => {
|
|
17
|
+
if (!existsSync(target)) return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: `${target} does not exist`
|
|
20
|
+
};
|
|
21
|
+
const root = projectRootOf(realpathSync(target));
|
|
22
|
+
const dotGit = path.join(root, ".git");
|
|
23
|
+
if (!existsSync(dotGit)) return {
|
|
24
|
+
ok: false,
|
|
25
|
+
error: `${target} is not in a git repository`
|
|
26
|
+
};
|
|
27
|
+
if (statSync(dotGit).isFile()) return {
|
|
28
|
+
ok: false,
|
|
29
|
+
error: `${root} is a git worktree; register the main clone instead`
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
ok: true,
|
|
33
|
+
root
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Attaches the repository at `target`: creates `~/.ork/projects/<id>/workflows`
|
|
38
|
+
* and records the project. Registering it again returns the same project.
|
|
39
|
+
*/
|
|
40
|
+
const registerProject = (store, target, options = {}) => {
|
|
41
|
+
const clone = cloneOf(target);
|
|
42
|
+
if (!clone.ok) return clone;
|
|
43
|
+
const { root } = clone;
|
|
44
|
+
const projects = store.projects();
|
|
45
|
+
const existing = projects.find((p) => p.root === root);
|
|
46
|
+
if (existing?.mode === "attached") return {
|
|
47
|
+
ok: true,
|
|
48
|
+
project: existing,
|
|
49
|
+
created: false
|
|
50
|
+
};
|
|
51
|
+
if (existing !== void 0 || hasInRepoFiles(root)) return {
|
|
52
|
+
ok: false,
|
|
53
|
+
error: `${root} keeps Ork's files in its own .ork/ (in-repo), so it is not attached`
|
|
54
|
+
};
|
|
55
|
+
const taken = projects.map((p) => p.id);
|
|
56
|
+
if (options.id !== void 0) {
|
|
57
|
+
if (!ID.test(options.id)) return {
|
|
58
|
+
ok: false,
|
|
59
|
+
error: `--id \`${options.id}\` must be lowercase letters, digits, ".", "_" or "-"`
|
|
60
|
+
};
|
|
61
|
+
if (taken.includes(options.id)) return {
|
|
62
|
+
ok: false,
|
|
63
|
+
error: `a project is already registered as ${options.id}`
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const id = options.id ?? newProjectId(root, taken);
|
|
67
|
+
const project = {
|
|
68
|
+
id,
|
|
69
|
+
root,
|
|
70
|
+
mode: "attached",
|
|
71
|
+
dir: path.join(projectsHome(options.home), id)
|
|
72
|
+
};
|
|
73
|
+
mkdirSync(placeFiles(project).workflows, { recursive: true });
|
|
74
|
+
return {
|
|
75
|
+
ok: true,
|
|
76
|
+
project: store.addProject(project),
|
|
77
|
+
created: true
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Records the in-repo project at `cwd`'s git root, if it is not registered yet;
|
|
82
|
+
* an attached one stays attached (`ork init` must not take it over).
|
|
83
|
+
*/
|
|
84
|
+
const recordInRepo = (store, cwd) => {
|
|
85
|
+
const root = projectRootOf(realpathSync(cwd));
|
|
86
|
+
const projects = store.projects();
|
|
87
|
+
const existing = projects.find((p) => p.root === root);
|
|
88
|
+
if (existing?.mode === "attached") return {
|
|
89
|
+
ok: false,
|
|
90
|
+
error: `${root} is attached: its workflows are in ${shownPath(existing.dir, root)}, and Ork writes nothing into the repository`
|
|
91
|
+
};
|
|
92
|
+
if (existing !== void 0) return {
|
|
93
|
+
ok: true,
|
|
94
|
+
project: existing,
|
|
95
|
+
created: false
|
|
96
|
+
};
|
|
97
|
+
const project = {
|
|
98
|
+
...inRepoPlace(root),
|
|
99
|
+
id: newProjectId(root, projects.map((p) => p.id))
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
ok: true,
|
|
103
|
+
project: store.addProject(project),
|
|
104
|
+
created: true
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Points a registered project at its clone's new place, after the clone was
|
|
109
|
+
* moved or renamed; its runs follow, and an in-repo project's `.ork/` with it.
|
|
110
|
+
*/
|
|
111
|
+
const relocateProject = (store, id, target) => {
|
|
112
|
+
const projects = store.projects();
|
|
113
|
+
const project = projects.find((p) => p.id === id);
|
|
114
|
+
if (project === void 0) return {
|
|
115
|
+
ok: false,
|
|
116
|
+
error: `No project is registered as ${id}.`
|
|
117
|
+
};
|
|
118
|
+
const clone = cloneOf(target);
|
|
119
|
+
if (!clone.ok) return clone;
|
|
120
|
+
const { root } = clone;
|
|
121
|
+
const other = projects.find((p) => p.root === root && p.id !== id);
|
|
122
|
+
if (other !== void 0) return {
|
|
123
|
+
ok: false,
|
|
124
|
+
error: `${root} is already registered as ${other.id}`
|
|
125
|
+
};
|
|
126
|
+
const dir = project.mode === "in-repo" ? inRepoPlace(root).dir : project.dir;
|
|
127
|
+
store.moveProject(id, {
|
|
128
|
+
root,
|
|
129
|
+
mode: project.mode,
|
|
130
|
+
dir
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
ok: true,
|
|
134
|
+
project: {
|
|
135
|
+
...project,
|
|
136
|
+
root,
|
|
137
|
+
dir
|
|
138
|
+
},
|
|
139
|
+
created: false
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* One project's lines for `ork projects`; rich, its mode and a missing clone
|
|
144
|
+
* are chips, its id is padded to `idWidth` and its root is cut to the screen.
|
|
145
|
+
*/
|
|
146
|
+
const formatProject = (project, term = termOf(process.stdout), idWidth = 0) => {
|
|
147
|
+
const missing = !existsSync(project.root);
|
|
148
|
+
if (!term.rich) {
|
|
149
|
+
const gone = missing ? style("yellow", " (missing)") : "";
|
|
150
|
+
return [`${style("bold", project.id)} ${style("dim", project.mode)} ${project.root}${gone}`, style("dim", ` files: ${shownPath(project.dir, project.root)}`)];
|
|
151
|
+
}
|
|
152
|
+
const mode = chip(term, project.mode.toUpperCase(), "muted");
|
|
153
|
+
const gone = missing ? ` ${chip(term, "MISSING", "warn")}` : "";
|
|
154
|
+
const room = term.width - (idWidth + 2 + project.mode.length + 2 + 2) - (missing ? 10 : 0);
|
|
155
|
+
return [`${style("bold", project.id.padEnd(idWidth))} ${mode} ${cut(project.root, Math.max(8, room))}${gone}`, style("dim", cut(` files: ${shownPath(project.dir, project.root)}`, term.width))];
|
|
156
|
+
};
|
|
157
|
+
/** Every project's lines, their ids aligned when rich. */
|
|
158
|
+
const formatProjects = (projects, term = termOf(process.stdout)) => {
|
|
159
|
+
const idWidth = term.rich ? Math.max(0, ...projects.map((p) => p.id.length)) : 0;
|
|
160
|
+
return projects.flatMap((p) => formatProject(p, term, idWidth));
|
|
161
|
+
};
|
|
162
|
+
/** What `ork register` prints: the project, and where its files go. */
|
|
163
|
+
const formatRegistered = (project, created) => {
|
|
164
|
+
const files = placeFiles(project);
|
|
165
|
+
const shown = (file) => shownPath(file, project.root);
|
|
166
|
+
return [
|
|
167
|
+
`${style("green", created ? "registered" : "already registered")} ${project.id} → ${project.root}`,
|
|
168
|
+
`\nWorkflows: ${shown(files.workflows)}/ · rules: ${shown(files.rules)} · runs: ${shown(files.runs)}/`,
|
|
169
|
+
`Nothing is written into ${project.root}. In it, ${style("bold", "ork run <name>")} finds the workflows above.`
|
|
170
|
+
];
|
|
171
|
+
};
|
|
172
|
+
// src/commands/project-records.ts
|
|
173
|
+
/**
|
|
174
|
+
* @file `ork projects`' subcommands on one project's record (ADR-035): `forget`
|
|
175
|
+
* drops it and keeps its files and runs; `move` points it at its clone's new
|
|
176
|
+
* place after the clone was moved or renamed, and its runs follow.
|
|
177
|
+
*/
|
|
178
|
+
/** Runs `use` with the store open, and closes it. */
|
|
179
|
+
const withStore = (use) => {
|
|
180
|
+
const store = openStore();
|
|
181
|
+
try {
|
|
182
|
+
return use(store);
|
|
183
|
+
} finally {
|
|
184
|
+
store.close();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const id = {
|
|
188
|
+
type: "positional",
|
|
189
|
+
description: "The project's id",
|
|
190
|
+
required: true
|
|
191
|
+
};
|
|
192
|
+
const forget = defineCommand({
|
|
193
|
+
meta: {
|
|
194
|
+
name: "forget",
|
|
195
|
+
description: "Forget a registered project; its files and runs are kept"
|
|
196
|
+
},
|
|
197
|
+
args: { id },
|
|
198
|
+
run: ({ args }) => {
|
|
199
|
+
if (withStore((store) => store.forgetProject(args.id))) {
|
|
200
|
+
write(`${style("green", "forgot")} ${args.id} (its files are kept)`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
writeErr(`No project is registered as ${args.id}.`);
|
|
204
|
+
process.exitCode = 1;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
const move = defineCommand({
|
|
208
|
+
meta: {
|
|
209
|
+
name: "move",
|
|
210
|
+
description: "Point a registered project at its clone's new place, after moving or renaming it"
|
|
211
|
+
},
|
|
212
|
+
args: {
|
|
213
|
+
id,
|
|
214
|
+
path: {
|
|
215
|
+
type: "positional",
|
|
216
|
+
description: "Where the clone is now",
|
|
217
|
+
required: true
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
run: ({ args }) => {
|
|
221
|
+
const result = withStore((store) => relocateProject(store, args.id, args.path));
|
|
222
|
+
if (result.ok) {
|
|
223
|
+
write(`${style("green", "moved")} ${args.id} → ${result.project.root}`);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
writeErr(result.error);
|
|
227
|
+
process.exitCode = 1;
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
export { formatRegistered as a, formatProjects as i, move as n, recordInRepo as o, withStore as r, registerProject as s, forget as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cn as linkNodes, L as openStore, wn as unlinkNodes, xn as addressOf } from "./src-DN-RPsil.mjs";
|
|
2
2
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
3
3
|
import { defineCommand } from "citty";
|
|
4
4
|
// src/commands/relay.ts
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { h as nodeSession, n as ORK_VERSION, v as findFollowUp } from "./__build_info__-
|
|
4
|
-
import { n as newRunId } from "./find-
|
|
1
|
+
import { Ct as startRun, G as parseInputPairs, Gn as endOf, Hn as loadProject, Ir as runDirOf, K as resolveInputs, L as openStore, Nr as placeFiles, Pn as templateOf, Qr as beforeOf, Qt as git, Sn as endLinksOf, St as walkSummary, Ti as DRIVER_IDS, Tt as userMessageText, U as createReplay, Un as machineRulesOf, Vn as gitRulesOf, W as replayLoopAnswers, Wn as createSignals, Zt as inspectProject, _n as deliverFollowUp, _r as maskReplacer, _t as planNodeSession, ar as createFeedback, at as adoptedCalls, ct as DETACHED_ENV, dn as createFollowUps, dr as renderTemplate, dt as NOT_STARTED, et as createRelay, fn as checkFollowUpsDue, gn as takeFollowUps, in as sessionDriver, it as createCalls, kn as liveStatus, lt as detachRun, m as resolveBase, mi as retiredDriverHint, mr as socketPath, n as resumedOptions, pr as serveRun, t as createWorkspace, tr as runGh, ui as isClaudeNode, ur as parseTemplate, wi as AGENT_DRIVERS, xi as readyDriver, zr as inside } from "./src-DN-RPsil.mjs";
|
|
2
|
+
import { c as callsShown, d as createDecisionQueue, l as createTerminalHuman, o as formatEvent, s as formatRunEvent, t as attachRun } from "./attach-B-FeE1dJ.mjs";
|
|
3
|
+
import { h as nodeSession, n as ORK_VERSION, v as findFollowUp } from "./__build_info__-DcRdK0Du.mjs";
|
|
4
|
+
import { n as newRunId } from "./find-mLYsR0uC.mjs";
|
|
5
5
|
import { c as write, i as detachHint, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
6
|
-
import { _ as namedMcpEntries, a as builtinExecutors, d as maskedEnv, f as maskedNamesOfRun, g as clearOutputFiles, h as sessionEnv, i as onPath, l as clearStateFiles, m as runScrubber, n as missingProgramMessage, r as missingPrograms, t as envProblems, v as resultOf } from "./src-
|
|
7
|
-
import { i as refusedBuiltin, o as workflowArg } from "./workflows-
|
|
8
|
-
import { a as formatReport, c as checksHere, d as unfitLines, i as walkLoaded, l as chooseReadyDriver, o as warningLines, s as budgetWarningLines, t as loadWorkflow, u as
|
|
6
|
+
import { _ as namedMcpEntries, a as builtinExecutors, d as maskedEnv, f as maskedNamesOfRun, g as clearOutputFiles, h as sessionEnv, i as onPath, l as clearStateFiles, m as runScrubber, n as missingProgramMessage, r as missingPrograms, t as envProblems, v as resultOf } from "./src-DHDQ0itC.mjs";
|
|
7
|
+
import { i as refusedBuiltin, o as workflowArg } from "./workflows-Bvl2Fquu.mjs";
|
|
8
|
+
import { a as formatReport, c as checksHere, d as runReadyDriver, f as unfitLines, i as walkLoaded, l as chooseReadyDriver, o as warningLines, s as budgetWarningLines, t as loadWorkflow, u as overrideRefusal } from "./validate-BVrT43GO.mjs";
|
|
9
9
|
import { a as createView, o as styler } from "./verdict-CMvPCpWC.mjs";
|
|
10
|
-
import { i as runLimits, r as limitsRefusal, t as chatNotice } from "./limits-
|
|
10
|
+
import { i as runLimits, r as limitsRefusal, t as chatNotice } from "./limits-C_Xz_t3C.mjs";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { appendFileSync, existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -478,9 +478,17 @@ const followUpSink = (options) => (input, at) => {
|
|
|
478
478
|
...options.gh === void 0 ? {} : { gh: options.gh }
|
|
479
479
|
});
|
|
480
480
|
};
|
|
481
|
+
/** Gh's own words when it has no login. */
|
|
482
|
+
const SIGNED_OUT = /not logged in|gh auth login/iu;
|
|
483
|
+
/**
|
|
484
|
+
* A gh error's first line, without a trailing period, so the notice is one
|
|
485
|
+
* line.
|
|
486
|
+
*/
|
|
487
|
+
const oneLine = (error) => (error.trim().split("\n")[0] ?? "").trim().replace(/\.$/u, "");
|
|
481
488
|
/**
|
|
482
489
|
* Moves the project's follow-ups whose time has come to due, as every `ork
|
|
483
|
-
* follow-ups` call does first. `gh` failing only warns, through `warn
|
|
490
|
+
* follow-ups` call does first. `gh` failing only warns, through `warn`: one
|
|
491
|
+
* line per call, however many refs failed.
|
|
484
492
|
*/
|
|
485
493
|
const refreshDue = async (store, project, warn, gh = runGh) => {
|
|
486
494
|
try {
|
|
@@ -489,7 +497,8 @@ const refreshDue = async (store, project, warn, gh = runGh) => {
|
|
|
489
497
|
project,
|
|
490
498
|
gh
|
|
491
499
|
});
|
|
492
|
-
|
|
500
|
+
const [first] = checked.errors;
|
|
501
|
+
if (first !== void 0) warn(checked.errors.some((error) => SIGNED_OUT.test(error)) ? "Can't check PRs: `gh` isn't signed in. After-merge follow-ups stay waiting; run `gh auth login` yourself." : `Can't check PRs: ${oneLine(first)}. After-merge follow-ups stay waiting.`);
|
|
493
502
|
return checked.due;
|
|
494
503
|
} catch (error) {
|
|
495
504
|
warn(`couldn't check what is due: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -610,6 +619,10 @@ const runNode = async (options) => {
|
|
|
610
619
|
named: plan.driver,
|
|
611
620
|
pinned: plan.pinned
|
|
612
621
|
});
|
|
622
|
+
if (options.driver !== void 0 && named === options.driver) {
|
|
623
|
+
const refusal = await overrideRefusal(options.driver, options.driverChecks);
|
|
624
|
+
if (refusal.length > 0) return failed(refusal);
|
|
625
|
+
}
|
|
613
626
|
const ready = named === void 0 ? chooseReadyDriver([options.nodeId], true, await (options.driverChecks ?? checksHere)()) : null;
|
|
614
627
|
if (ready?.ok === false) return failed(ready.lines);
|
|
615
628
|
if (ready?.line !== void 0) options.err(ready.line);
|
|
@@ -1238,7 +1251,7 @@ const isDriver = (value) => AGENT_DRIVERS.some((d) => d.id === value);
|
|
|
1238
1251
|
/** Why `--driver` refuses a value: a retired id names its replacement. */
|
|
1239
1252
|
const badDriver = (value) => `--${retiredDriverHint(value) ?? `driver must be one of ${AGENT_DRIVERS.map((d) => d.id).join(", ")}, got \`${value}\``}`;
|
|
1240
1253
|
/** Loads the drivers only when a run starts, so other commands stay fast. */
|
|
1241
|
-
const loadRuntime = async (driver, runs) => (await import("./src-
|
|
1254
|
+
const loadRuntime = async (driver, runs) => (await import("./src-CXBmaGwS.mjs")).createRuntime(driver, sessionEnv(process.env), runs);
|
|
1242
1255
|
/**
|
|
1243
1256
|
* Ctrl-C asks the run to stop, and so does a terminal closing or a polite kill,
|
|
1244
1257
|
* so that the run ends tidily and leaves no result unscrubbed.
|
|
@@ -1293,7 +1306,7 @@ const run = defineCommand({
|
|
|
1293
1306
|
},
|
|
1294
1307
|
driver: {
|
|
1295
1308
|
type: "string",
|
|
1296
|
-
description: "
|
|
1309
|
+
description: `${DRIVER_IDS.join(", ")} (default: the driver ready here)`
|
|
1297
1310
|
},
|
|
1298
1311
|
"in-place": {
|
|
1299
1312
|
type: "boolean",
|
|
@@ -1393,7 +1406,7 @@ const run = defineCommand({
|
|
|
1393
1406
|
}
|
|
1394
1407
|
return;
|
|
1395
1408
|
}
|
|
1396
|
-
const { prepareFollowUps } = await import("./brief-
|
|
1409
|
+
const { prepareFollowUps } = await import("./brief-BvMtIFio.mjs");
|
|
1397
1410
|
const taking = prepareFollowUps(store, rawArgs, args["run-id"], target);
|
|
1398
1411
|
if (taking === void 0) {
|
|
1399
1412
|
store.close();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as gitOk, Qt as git } from "./src-DN-RPsil.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as sendFromScript, L as openStore, Q as scriptRefusal, Z as TOO_LONG } from "./src-DN-RPsil.mjs";
|
|
2
2
|
import { l as writeErr } from "./output-B1kwo0YU.mjs";
|
|
3
|
-
import { u as inheritedScrubber } from "./src-
|
|
3
|
+
import { u as inheritedScrubber } from "./src-DHDQ0itC.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
// src/commands/send.ts
|
|
6
6
|
/**
|