ue-mcp 1.0.27 → 1.0.29

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.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `npx ue-mcp feedback <list|show|approve|discard>` — review and act on
4
+ * submissions that ue-mcp deferred to disk while running in
5
+ * `feedback.mode = "defer"`. Pairs with src/feedback-deferred.ts.
6
+ *
7
+ * Argv layout after index.ts splices "feedback" out:
8
+ * argv[2] = subcommand (list, show, approve, discard)
9
+ * argv[3] = id (for show/approve/discard)
10
+ */
11
+ export {};
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `npx ue-mcp feedback <list|show|approve|discard>` — review and act on
4
+ * submissions that ue-mcp deferred to disk while running in
5
+ * `feedback.mode = "defer"`. Pairs with src/feedback-deferred.ts.
6
+ *
7
+ * Argv layout after index.ts splices "feedback" out:
8
+ * argv[2] = subcommand (list, show, approve, discard)
9
+ * argv[3] = id (for show/approve/discard)
10
+ */
11
+ import { deleteDeferred, getPendingDir, listDeferred, loadDeferred, } from "./feedback-deferred.js";
12
+ import { submitFeedback } from "./github-app.js";
13
+ import { BOLD, CYAN, DIM, RED, RESET, YELLOW, fail, info, ok, warn, } from "./ui/ansi.js";
14
+ function printHelp() {
15
+ console.log("");
16
+ console.log(` ${BOLD}${CYAN}ue-mcp feedback${RESET}`);
17
+ console.log("");
18
+ console.log(` Review submissions deferred while \`feedback.mode = "defer"\` was active.`);
19
+ console.log(` Pending submissions are stored in: ${DIM}${getPendingDir()}${RESET}`);
20
+ console.log("");
21
+ console.log(` ${BOLD}list${RESET} List every pending submission (id, project, title)`);
22
+ console.log(` ${BOLD}show${RESET} <id> Print the full body and metadata for one entry`);
23
+ console.log(` ${BOLD}approve${RESET} <id> POST the entry to GitHub, then delete it locally`);
24
+ console.log(` ${BOLD}discard${RESET} <id> Delete the entry without posting`);
25
+ console.log("");
26
+ }
27
+ function cmdList() {
28
+ const entries = listDeferred();
29
+ if (entries.length === 0) {
30
+ info("No pending feedback submissions.");
31
+ info(getPendingDir());
32
+ return;
33
+ }
34
+ console.log("");
35
+ console.log(` ${BOLD}${entries.length} pending feedback submission(s)${RESET}`);
36
+ console.log("");
37
+ const idWidth = Math.max(...entries.map((e) => e.id.length));
38
+ const projWidth = Math.max("project".length, ...entries.map((e) => (e.project ?? "(none)").length));
39
+ console.log(` ${DIM}${"id".padEnd(idWidth)} ${"project".padEnd(projWidth)} ${"author".padEnd(4)} title${RESET}`);
40
+ for (const e of entries) {
41
+ const projLabel = (e.project ?? "(none)").padEnd(projWidth);
42
+ const titlePreview = e.title.length > 70 ? `${e.title.slice(0, 67)}...` : e.title;
43
+ console.log(` ${e.id.padEnd(idWidth)} ${projLabel} ${e.author.padEnd(4)} ${titlePreview}`);
44
+ }
45
+ console.log("");
46
+ console.log(` ${DIM}Approve with: npx ue-mcp feedback approve <id>${RESET}`);
47
+ console.log(` ${DIM}Discard with: npx ue-mcp feedback discard <id>${RESET}`);
48
+ console.log("");
49
+ }
50
+ function cmdShow(id) {
51
+ const entry = loadDeferred(id);
52
+ if (!entry) {
53
+ fail(`No pending feedback with id "${id}".`);
54
+ process.exit(1);
55
+ }
56
+ console.log("");
57
+ console.log(` ${BOLD}id ${RESET}${entry.id}`);
58
+ console.log(` ${BOLD}created ${RESET}${entry.createdAt}`);
59
+ console.log(` ${BOLD}project ${RESET}${entry.project ?? "(none)"}`);
60
+ console.log(` ${BOLD}author ${RESET}${entry.author}`);
61
+ console.log(` ${BOLD}labels ${RESET}${entry.labels.join(", ")}`);
62
+ console.log(` ${BOLD}title ${RESET}${entry.title}`);
63
+ console.log("");
64
+ console.log(` ${BOLD}── BODY ─────────────────────────────────────${RESET}`);
65
+ console.log(entry.body);
66
+ console.log(` ${BOLD}── END BODY ─────────────────────────────────${RESET}`);
67
+ console.log("");
68
+ }
69
+ async function cmdApprove(id) {
70
+ const entry = loadDeferred(id);
71
+ if (!entry) {
72
+ fail(`No pending feedback with id "${id}".`);
73
+ process.exit(1);
74
+ }
75
+ console.log("");
76
+ info(`Posting ${id} to GitHub as ${entry.author === "bot" ? "ue-mcp-feedback bot" : "your GitHub user"}...`);
77
+ let result;
78
+ try {
79
+ result = await submitFeedback(entry.title, entry.body, entry.labels, {
80
+ useBot: entry.author === "bot",
81
+ });
82
+ }
83
+ catch (e) {
84
+ fail(`GitHub POST failed: ${e instanceof Error ? e.message : String(e)}`);
85
+ info(`Entry left on disk; retry with: npx ue-mcp feedback approve ${id}`);
86
+ process.exit(1);
87
+ }
88
+ if (result.kind === "auth_required") {
89
+ warn("GitHub auth required to post as user.");
90
+ console.log(` ${BOLD}1.${RESET} Open: ${CYAN}${result.verification_uri}${RESET}`);
91
+ console.log(` ${BOLD}2.${RESET} Enter code: ${BOLD}${YELLOW}${result.user_code}${RESET}`);
92
+ console.log(` ${BOLD}3.${RESET} Authorize, then re-run: npx ue-mcp feedback approve ${id}`);
93
+ info(`Or discard with: npx ue-mcp feedback discard ${id}`);
94
+ process.exit(1);
95
+ }
96
+ ok(`Posted as issue #${result.number} (${result.url})`);
97
+ if (deleteDeferred(id)) {
98
+ info(`Removed local entry ${id}.`);
99
+ }
100
+ console.log("");
101
+ }
102
+ function cmdDiscard(id) {
103
+ const entry = loadDeferred(id);
104
+ if (!entry) {
105
+ fail(`No pending feedback with id "${id}".`);
106
+ process.exit(1);
107
+ }
108
+ if (deleteDeferred(id)) {
109
+ ok(`Discarded ${id} (was: "${entry.title}").`);
110
+ }
111
+ else {
112
+ fail(`Failed to delete ${id}.`);
113
+ process.exit(1);
114
+ }
115
+ }
116
+ async function main() {
117
+ const sub = process.argv[2];
118
+ const id = process.argv[3];
119
+ switch (sub) {
120
+ case "list":
121
+ cmdList();
122
+ return;
123
+ case "show":
124
+ if (!id) {
125
+ fail("Usage: npx ue-mcp feedback show <id>");
126
+ process.exit(1);
127
+ }
128
+ cmdShow(id);
129
+ return;
130
+ case "approve":
131
+ if (!id) {
132
+ fail("Usage: npx ue-mcp feedback approve <id>");
133
+ process.exit(1);
134
+ }
135
+ await cmdApprove(id);
136
+ return;
137
+ case "discard":
138
+ if (!id) {
139
+ fail("Usage: npx ue-mcp feedback discard <id>");
140
+ process.exit(1);
141
+ }
142
+ cmdDiscard(id);
143
+ return;
144
+ case undefined:
145
+ case "help":
146
+ case "--help":
147
+ case "-h":
148
+ printHelp();
149
+ return;
150
+ default:
151
+ fail(`Unknown subcommand: feedback ${sub}`);
152
+ printHelp();
153
+ process.exit(1);
154
+ }
155
+ }
156
+ main().catch((e) => {
157
+ console.error(`\n ${RED}Fatal error: ${e instanceof Error ? e.message : e}${RESET}\n`);
158
+ process.exit(1);
159
+ });
160
+ //# sourceMappingURL=feedback-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-cli.js","sourceRoot":"","sources":["../src/feedback-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface DeferredFeedback {
2
+ /** Stable id derived from timestamp + random suffix; matches the filename. */
3
+ id: string;
4
+ /** ISO-8601 timestamp captured at defer time. */
5
+ createdAt: string;
6
+ /** Project name that originated the submission, or null if none was loaded. */
7
+ project: string | null;
8
+ /** Scrubbed issue title. */
9
+ title: string;
10
+ /** Scrubbed issue body. */
11
+ body: string;
12
+ /** Inferred GitHub labels. */
13
+ labels: string[];
14
+ /** Authorship intent at defer time. Honored when the deferred entry is
15
+ * later approved via the CLI. */
16
+ author: "user" | "bot";
17
+ }
18
+ export declare function deferSubmission(payload: {
19
+ title: string;
20
+ body: string;
21
+ labels: string[];
22
+ }, project: string | null, author: "user" | "bot"): DeferredFeedback;
23
+ export declare function listDeferred(): DeferredFeedback[];
24
+ export declare function loadDeferred(id: string): DeferredFeedback | null;
25
+ export declare function deleteDeferred(id: string): boolean;
26
+ export declare function getPendingDir(): string;
@@ -0,0 +1,96 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import * as os from "node:os";
4
+ import { randomBytes } from "node:crypto";
5
+ /**
6
+ * Storage for `feedback.mode = "defer"` submissions. The server writes the
7
+ * fully-scrubbed payload (title + body + labels + author) to disk so a human
8
+ * can review, approve, or discard later via `npx ue-mcp feedback ...`.
9
+ *
10
+ * Location: ~/.ue-mcp/pending-feedback/<sortable-id>.json
11
+ *
12
+ * User-scoped (not project-scoped) because feedback issues file against the
13
+ * shared ue-mcp tracker, not against the user's project. The recorded
14
+ * `project` field on each entry remembers which project originated the
15
+ * submission so the reviewer has context.
16
+ */
17
+ /** Resolved per call so tests (and runtime overrides) can change the env var
18
+ * between operations without re-importing the module. */
19
+ function pendingDir() {
20
+ return (process.env.UE_MCP_PENDING_DIR ||
21
+ path.join(os.homedir(), ".ue-mcp", "pending-feedback"));
22
+ }
23
+ function ensureDir() {
24
+ const dir = pendingDir();
25
+ if (!fs.existsSync(dir)) {
26
+ fs.mkdirSync(dir, { recursive: true });
27
+ }
28
+ }
29
+ function generateId(now) {
30
+ // Sortable: YYYYMMDDTHHmmssSSS-<6 hex>. Millisecond precision so two
31
+ // entries created back-to-back in the same second still sort by
32
+ // insertion order before the random suffix tiebreak kicks in.
33
+ const pad = (n, w = 2) => String(n).padStart(w, "0");
34
+ const ts = `${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}T${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}${pad(now.getUTCMilliseconds(), 3)}`;
35
+ const rand = randomBytes(3).toString("hex");
36
+ return `${ts}-${rand}`;
37
+ }
38
+ export function deferSubmission(payload, project, author) {
39
+ ensureDir();
40
+ const now = new Date();
41
+ const id = generateId(now);
42
+ const entry = {
43
+ id,
44
+ createdAt: now.toISOString(),
45
+ project,
46
+ title: payload.title,
47
+ body: payload.body,
48
+ labels: payload.labels,
49
+ author,
50
+ };
51
+ const filePath = path.join(pendingDir(), `${id}.json`);
52
+ fs.writeFileSync(filePath, JSON.stringify(entry, null, 2), { mode: 0o600 });
53
+ return entry;
54
+ }
55
+ export function listDeferred() {
56
+ const dir = pendingDir();
57
+ if (!fs.existsSync(dir))
58
+ return [];
59
+ const entries = [];
60
+ for (const name of fs.readdirSync(dir).sort()) {
61
+ if (!name.endsWith(".json"))
62
+ continue;
63
+ try {
64
+ const raw = fs.readFileSync(path.join(dir, name), "utf-8");
65
+ const parsed = JSON.parse(raw);
66
+ entries.push(parsed);
67
+ }
68
+ catch {
69
+ // Skip unreadable / malformed entries silently. They stay on disk for
70
+ // the user to inspect manually if they care.
71
+ }
72
+ }
73
+ return entries;
74
+ }
75
+ export function loadDeferred(id) {
76
+ const filePath = path.join(pendingDir(), `${id}.json`);
77
+ if (!fs.existsSync(filePath))
78
+ return null;
79
+ try {
80
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ export function deleteDeferred(id) {
87
+ const filePath = path.join(pendingDir(), `${id}.json`);
88
+ if (!fs.existsSync(filePath))
89
+ return false;
90
+ fs.unlinkSync(filePath);
91
+ return true;
92
+ }
93
+ export function getPendingDir() {
94
+ return pendingDir();
95
+ }
96
+ //# sourceMappingURL=feedback-deferred.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-deferred.js","sourceRoot":"","sources":["../src/feedback-deferred.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,100 @@
1
1
  import { z } from "zod";
2
+ /**
3
+ * The `ue-mcp:` block at the top of ue-mcp.yml. Historically just had
4
+ * `version: 1`. As of 1.0.29, also hosts the project-level config that
5
+ * used to live in the separate `.ue-mcp.json` file (killed for one-config-
6
+ * format consistency).
7
+ *
8
+ * ue-mcp:
9
+ * version: 1
10
+ * contentRoots: ["/Game/"]
11
+ * disable: ["gas"]
12
+ * http: { enabled: false, port: 7723 }
13
+ * feedback: { mode: "interactive" }
14
+ * installedHooks: [...] # user-local; lives in ue-mcp.local.yml
15
+ *
16
+ * Tracked vs untracked split is by convention:
17
+ * ue-mcp.yml - tracked. version, contentRoots, disable, http, feedback.
18
+ * ue-mcp.local.yml - gitignored. installedHooks and anything else user-local.
19
+ * flowkit's loader deep-merges local on top of yml so both surface as one
20
+ * resolved config to the server.
21
+ */
2
22
  export declare const FlowVersionSchema: z.ZodObject<{
3
23
  version: z.ZodLiteral<1>;
4
- }, "strip", z.ZodTypeAny, {
5
- version: 1;
6
- }, {
7
- version: 1;
8
- }>;
24
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
26
+ http: z.ZodOptional<z.ZodObject<{
27
+ enabled: z.ZodOptional<z.ZodBoolean>;
28
+ port: z.ZodOptional<z.ZodNumber>;
29
+ host: z.ZodOptional<z.ZodString>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ enabled?: boolean | undefined;
32
+ port?: number | undefined;
33
+ host?: string | undefined;
34
+ }, {
35
+ enabled?: boolean | undefined;
36
+ port?: number | undefined;
37
+ host?: string | undefined;
38
+ }>>;
39
+ feedback: z.ZodOptional<z.ZodObject<{
40
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
41
+ }, "strip", z.ZodTypeAny, {
42
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
43
+ }, {
44
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
45
+ }>>;
46
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
47
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
48
+ version: z.ZodLiteral<1>;
49
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
50
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
51
+ http: z.ZodOptional<z.ZodObject<{
52
+ enabled: z.ZodOptional<z.ZodBoolean>;
53
+ port: z.ZodOptional<z.ZodNumber>;
54
+ host: z.ZodOptional<z.ZodString>;
55
+ }, "strip", z.ZodTypeAny, {
56
+ enabled?: boolean | undefined;
57
+ port?: number | undefined;
58
+ host?: string | undefined;
59
+ }, {
60
+ enabled?: boolean | undefined;
61
+ port?: number | undefined;
62
+ host?: string | undefined;
63
+ }>>;
64
+ feedback: z.ZodOptional<z.ZodObject<{
65
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
66
+ }, "strip", z.ZodTypeAny, {
67
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
68
+ }, {
69
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
70
+ }>>;
71
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
72
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
73
+ version: z.ZodLiteral<1>;
74
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
75
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
76
+ http: z.ZodOptional<z.ZodObject<{
77
+ enabled: z.ZodOptional<z.ZodBoolean>;
78
+ port: z.ZodOptional<z.ZodNumber>;
79
+ host: z.ZodOptional<z.ZodString>;
80
+ }, "strip", z.ZodTypeAny, {
81
+ enabled?: boolean | undefined;
82
+ port?: number | undefined;
83
+ host?: string | undefined;
84
+ }, {
85
+ enabled?: boolean | undefined;
86
+ port?: number | undefined;
87
+ host?: string | undefined;
88
+ }>>;
89
+ feedback: z.ZodOptional<z.ZodObject<{
90
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
91
+ }, "strip", z.ZodTypeAny, {
92
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
93
+ }, {
94
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
95
+ }>>;
96
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
97
+ }, z.ZodTypeAny, "passthrough">>;
9
98
  export declare const FlowProjectSchema: z.ZodOptional<z.ZodObject<{
10
99
  name: z.ZodOptional<z.ZodString>;
11
100
  engine: z.ZodOptional<z.ZodString>;
@@ -343,11 +432,80 @@ export declare const FlowConfigSchema: z.ZodObject<{
343
432
  } & {
344
433
  "ue-mcp": z.ZodOptional<z.ZodObject<{
345
434
  version: z.ZodLiteral<1>;
346
- }, "strip", z.ZodTypeAny, {
347
- version: 1;
348
- }, {
349
- version: 1;
350
- }>>;
435
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
436
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
437
+ http: z.ZodOptional<z.ZodObject<{
438
+ enabled: z.ZodOptional<z.ZodBoolean>;
439
+ port: z.ZodOptional<z.ZodNumber>;
440
+ host: z.ZodOptional<z.ZodString>;
441
+ }, "strip", z.ZodTypeAny, {
442
+ enabled?: boolean | undefined;
443
+ port?: number | undefined;
444
+ host?: string | undefined;
445
+ }, {
446
+ enabled?: boolean | undefined;
447
+ port?: number | undefined;
448
+ host?: string | undefined;
449
+ }>>;
450
+ feedback: z.ZodOptional<z.ZodObject<{
451
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
452
+ }, "strip", z.ZodTypeAny, {
453
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
454
+ }, {
455
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
456
+ }>>;
457
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
458
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
459
+ version: z.ZodLiteral<1>;
460
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
461
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
462
+ http: z.ZodOptional<z.ZodObject<{
463
+ enabled: z.ZodOptional<z.ZodBoolean>;
464
+ port: z.ZodOptional<z.ZodNumber>;
465
+ host: z.ZodOptional<z.ZodString>;
466
+ }, "strip", z.ZodTypeAny, {
467
+ enabled?: boolean | undefined;
468
+ port?: number | undefined;
469
+ host?: string | undefined;
470
+ }, {
471
+ enabled?: boolean | undefined;
472
+ port?: number | undefined;
473
+ host?: string | undefined;
474
+ }>>;
475
+ feedback: z.ZodOptional<z.ZodObject<{
476
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
477
+ }, "strip", z.ZodTypeAny, {
478
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
479
+ }, {
480
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
481
+ }>>;
482
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
483
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
484
+ version: z.ZodLiteral<1>;
485
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
486
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
487
+ http: z.ZodOptional<z.ZodObject<{
488
+ enabled: z.ZodOptional<z.ZodBoolean>;
489
+ port: z.ZodOptional<z.ZodNumber>;
490
+ host: z.ZodOptional<z.ZodString>;
491
+ }, "strip", z.ZodTypeAny, {
492
+ enabled?: boolean | undefined;
493
+ port?: number | undefined;
494
+ host?: string | undefined;
495
+ }, {
496
+ enabled?: boolean | undefined;
497
+ port?: number | undefined;
498
+ host?: string | undefined;
499
+ }>>;
500
+ feedback: z.ZodOptional<z.ZodObject<{
501
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
502
+ }, "strip", z.ZodTypeAny, {
503
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
504
+ }, {
505
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
506
+ }>>;
507
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
508
+ }, z.ZodTypeAny, "passthrough">>>;
351
509
  project: z.ZodOptional<z.ZodObject<{
352
510
  name: z.ZodOptional<z.ZodString>;
353
511
  engine: z.ZodOptional<z.ZodString>;
@@ -441,9 +599,32 @@ export declare const FlowConfigSchema: z.ZodObject<{
441
599
  }[] | undefined;
442
600
  rollback_on_failure?: boolean | undefined;
443
601
  }>;
444
- "ue-mcp"?: {
445
- version: 1;
446
- } | undefined;
602
+ "ue-mcp"?: z.objectOutputType<{
603
+ version: z.ZodLiteral<1>;
604
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
605
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
606
+ http: z.ZodOptional<z.ZodObject<{
607
+ enabled: z.ZodOptional<z.ZodBoolean>;
608
+ port: z.ZodOptional<z.ZodNumber>;
609
+ host: z.ZodOptional<z.ZodString>;
610
+ }, "strip", z.ZodTypeAny, {
611
+ enabled?: boolean | undefined;
612
+ port?: number | undefined;
613
+ host?: string | undefined;
614
+ }, {
615
+ enabled?: boolean | undefined;
616
+ port?: number | undefined;
617
+ host?: string | undefined;
618
+ }>>;
619
+ feedback: z.ZodOptional<z.ZodObject<{
620
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
621
+ }, "strip", z.ZodTypeAny, {
622
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
623
+ }, {
624
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
625
+ }>>;
626
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
627
+ }, z.ZodTypeAny, "passthrough"> | undefined;
447
628
  project?: {
448
629
  name?: string | undefined;
449
630
  engine?: string | undefined;
@@ -455,9 +636,32 @@ export declare const FlowConfigSchema: z.ZodObject<{
455
636
  max_age_hours: number;
456
637
  } | undefined;
457
638
  }, {
458
- "ue-mcp"?: {
459
- version: 1;
460
- } | undefined;
639
+ "ue-mcp"?: z.objectInputType<{
640
+ version: z.ZodLiteral<1>;
641
+ contentRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
642
+ disable: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
643
+ http: z.ZodOptional<z.ZodObject<{
644
+ enabled: z.ZodOptional<z.ZodBoolean>;
645
+ port: z.ZodOptional<z.ZodNumber>;
646
+ host: z.ZodOptional<z.ZodString>;
647
+ }, "strip", z.ZodTypeAny, {
648
+ enabled?: boolean | undefined;
649
+ port?: number | undefined;
650
+ host?: string | undefined;
651
+ }, {
652
+ enabled?: boolean | undefined;
653
+ port?: number | undefined;
654
+ host?: string | undefined;
655
+ }>>;
656
+ feedback: z.ZodOptional<z.ZodObject<{
657
+ mode: z.ZodOptional<z.ZodEnum<["interactive", "auto-approve", "defer"]>>;
658
+ }, "strip", z.ZodTypeAny, {
659
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
660
+ }, {
661
+ mode?: "interactive" | "auto-approve" | "defer" | undefined;
662
+ }>>;
663
+ installedHooks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
664
+ }, z.ZodTypeAny, "passthrough"> | undefined;
461
665
  project?: {
462
666
  name?: string | undefined;
463
667
  engine?: string | undefined;
@@ -1,8 +1,43 @@
1
1
  import { z } from "zod";
2
2
  import { EngineConfigSchema } from "@db-lyon/flowkit";
3
+ /**
4
+ * The `ue-mcp:` block at the top of ue-mcp.yml. Historically just had
5
+ * `version: 1`. As of 1.0.29, also hosts the project-level config that
6
+ * used to live in the separate `.ue-mcp.json` file (killed for one-config-
7
+ * format consistency).
8
+ *
9
+ * ue-mcp:
10
+ * version: 1
11
+ * contentRoots: ["/Game/"]
12
+ * disable: ["gas"]
13
+ * http: { enabled: false, port: 7723 }
14
+ * feedback: { mode: "interactive" }
15
+ * installedHooks: [...] # user-local; lives in ue-mcp.local.yml
16
+ *
17
+ * Tracked vs untracked split is by convention:
18
+ * ue-mcp.yml - tracked. version, contentRoots, disable, http, feedback.
19
+ * ue-mcp.local.yml - gitignored. installedHooks and anything else user-local.
20
+ * flowkit's loader deep-merges local on top of yml so both surface as one
21
+ * resolved config to the server.
22
+ */
3
23
  export const FlowVersionSchema = z.object({
4
24
  version: z.literal(1),
5
- });
25
+ contentRoots: z.array(z.string()).optional(),
26
+ disable: z.array(z.string()).optional(),
27
+ http: z
28
+ .object({
29
+ enabled: z.boolean().optional(),
30
+ port: z.number().int().min(1).max(65535).optional(),
31
+ host: z.string().optional(),
32
+ })
33
+ .optional(),
34
+ feedback: z
35
+ .object({
36
+ mode: z.enum(["interactive", "auto-approve", "defer"]).optional(),
37
+ })
38
+ .optional(),
39
+ installedHooks: z.array(z.string()).optional(),
40
+ }).passthrough();
6
41
  export const FlowProjectSchema = z.object({
7
42
  name: z.string().optional(),
8
43
  engine: z.string().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/flow/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC;IACxD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACtC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACtC,OAAO,EAAE,iBAAiB;IAC1B,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/flow/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5C,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,CAAC;SACJ,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;QACnD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC5B,CAAC;SACD,QAAQ,EAAE;IACb,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;KAClE,CAAC;SACD,QAAQ,EAAE;IACb,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC;IACxD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACtC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACtC,OAAO,EAAE,iBAAiB;IAC1B,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC"}