dsh-trellis 0.1.0 → 0.1.2
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 +92 -80
- package/lib/client.js +475 -0
- package/lib/client.js.map +1 -0
- package/lib/commands.js +215 -195
- package/lib/config.js +77 -45
- package/lib/index.js +186 -146
- package/lib/wait-tool.js +192 -149
- package/package.json +114 -79
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState","useMemo"],"sources":["../src/client/form.js","../src/client/TrellisSettingsCard.jsx","../src/client/compat.js","../src/client/locales.js","../src/client/styles.js","../src/client/index.jsx"],"mappings":"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"}
|
package/lib/commands.js
CHANGED
|
@@ -1,195 +1,215 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Human-facing /trellis commands: status and finish.
|
|
3
|
-
*
|
|
4
|
-
* Command names follow the dsh grammar (lowercase letters, digits, `_`, `-`;
|
|
5
|
-
* no `:`), and deliberately avoid the skill names (`trellis-start`,
|
|
6
|
-
* `trellis-continue`, `trellis-finish-work`): a command sharing a skill name
|
|
7
|
-
* would shadow the skill's slash-pipeline injection. The Trellis session
|
|
8
|
-
* rituals stay on the skill surface; these commands cover the deterministic,
|
|
9
|
-
* zero-token side — pointer inspection and wrap-up.
|
|
10
|
-
*
|
|
11
|
-
* @module dsh-trellis/commands
|
|
12
|
-
*/
|
|
13
|
-
import { execFile } from "node:child_process";
|
|
14
|
-
import { promisify } from "node:util";
|
|
15
|
-
import { join } from "node:path";
|
|
16
|
-
import { findProjectRoot } from "./workflow.js";
|
|
17
|
-
import { nodeFs } from "./node-fs.js";
|
|
18
|
-
import { dshContextKey } from "./session-env.js";
|
|
19
|
-
|
|
20
|
-
const execFileAsync = promisify(execFile);
|
|
21
|
-
|
|
22
|
-
/** Platform-aware Python launch candidates. An explicit config disables fallback. */
|
|
23
|
-
export function pythonCandidates(config, platform = process.platform) {
|
|
24
|
-
if (config.pythonCmd) return [{ command: config.pythonCmd, prefixArgs: [] }];
|
|
25
|
-
if (platform === "win32") {
|
|
26
|
-
return [
|
|
27
|
-
{ command: "py", prefixArgs: ["-3"] },
|
|
28
|
-
{ command: "python", prefixArgs: [] },
|
|
29
|
-
];
|
|
30
|
-
}
|
|
31
|
-
return [
|
|
32
|
-
{ command: "python3", prefixArgs: [] },
|
|
33
|
-
{ command: "python", prefixArgs: [] },
|
|
34
|
-
];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Run a project Trellis script with bounded time and output. */
|
|
38
|
-
export async function runTrellisScript(
|
|
39
|
-
config,
|
|
40
|
-
root,
|
|
41
|
-
sessionId,
|
|
42
|
-
scriptArgs,
|
|
43
|
-
dependencies = {},
|
|
44
|
-
) {
|
|
45
|
-
const execute = dependencies.execFile ?? execFileAsync;
|
|
46
|
-
const platform = dependencies.platform ?? process.platform;
|
|
47
|
-
const signal = dependencies.signal;
|
|
48
|
-
const contextKey = dshContextKey(sessionId);
|
|
49
|
-
const env = {
|
|
50
|
-
...process.env,
|
|
51
|
-
...(contextKey
|
|
52
|
-
? {
|
|
53
|
-
TRELLIS_CONTEXT_ID: contextKey,
|
|
54
|
-
DSH_TRELLIS_CONTEXT_ID: contextKey,
|
|
55
|
-
DSH_SHELL: "1",
|
|
56
|
-
DSH_SESSION_ID: sessionId,
|
|
57
|
-
}
|
|
58
|
-
: {}),
|
|
59
|
-
};
|
|
60
|
-
const script = join(root, ".trellis", "scripts", "task.py");
|
|
61
|
-
const candidates = pythonCandidates(config, platform);
|
|
62
|
-
for (const [index, candidate] of candidates.entries()) {
|
|
63
|
-
const args = [...candidate.prefixArgs, script, ...scriptArgs];
|
|
64
|
-
try {
|
|
65
|
-
const { stdout, stderr } = await execute(candidate.command, args, {
|
|
66
|
-
cwd: root,
|
|
67
|
-
env,
|
|
68
|
-
windowsHide: true,
|
|
69
|
-
timeout: 15_000,
|
|
70
|
-
maxBuffer: 256 * 1024,
|
|
71
|
-
...(signal ? { signal } : {}),
|
|
72
|
-
});
|
|
73
|
-
const text = `${stdout}${stderr ? `\n${stderr}` : ""}`.trim();
|
|
74
|
-
return { kind: "success", text };
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (signal?.aborted || error?.name === "AbortError") {
|
|
77
|
-
return { kind: "error", text: "Trellis command cancelled." };
|
|
78
|
-
}
|
|
79
|
-
const missing = error?.code === "ENOENT";
|
|
80
|
-
if (missing && index < candidates.length - 1) continue;
|
|
81
|
-
const attempted = candidates
|
|
82
|
-
.slice(0, index + 1)
|
|
83
|
-
.map(({ command, prefixArgs }) => [command, ...prefixArgs].join(" "))
|
|
84
|
-
.join(", ");
|
|
85
|
-
const message = missing
|
|
86
|
-
? `Python command not found (tried: ${attempted}). Set the plugin's pythonCmd config to a Python 3 executable.`
|
|
87
|
-
: `Trellis script failed via ${[candidate.command, ...candidate.prefixArgs].join(" ")}: ${error?.message ?? String(error)}`;
|
|
88
|
-
return { kind: "error", text: message };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
kind: "error",
|
|
93
|
-
text: "No Python command candidates are configured.",
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Register the /trellis command family.
|
|
99
|
-
* @param {object} ctx - cordis context exposing `ctx.commands`.
|
|
100
|
-
* @param {object} resolved - normalized plugin config.
|
|
101
|
-
* @returns {() => void} disposer.
|
|
102
|
-
*/
|
|
103
|
-
export function registerCommands(ctx, resolved, dependencies = {}) {
|
|
104
|
-
const fs = dependencies.fs ?? nodeFs;
|
|
105
|
-
const execute = dependencies.execFile ?? execFileAsync;
|
|
106
|
-
const platform = dependencies.platform ?? process.platform;
|
|
107
|
-
const disposers = [];
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
113
|
-
return {
|
|
114
|
-
kind: "error",
|
|
115
|
-
text: "
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Human-facing /trellis commands: status and finish.
|
|
3
|
+
*
|
|
4
|
+
* Command names follow the dsh grammar (lowercase letters, digits, `_`, `-`;
|
|
5
|
+
* no `:`), and deliberately avoid the skill names (`trellis-start`,
|
|
6
|
+
* `trellis-continue`, `trellis-finish-work`): a command sharing a skill name
|
|
7
|
+
* would shadow the skill's slash-pipeline injection. The Trellis session
|
|
8
|
+
* rituals stay on the skill surface; these commands cover the deterministic,
|
|
9
|
+
* zero-token side — pointer inspection and wrap-up.
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-trellis/commands
|
|
12
|
+
*/
|
|
13
|
+
import { execFile } from "node:child_process";
|
|
14
|
+
import { promisify } from "node:util";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { findProjectRoot } from "./workflow.js";
|
|
17
|
+
import { nodeFs } from "./node-fs.js";
|
|
18
|
+
import { dshContextKey } from "./session-env.js";
|
|
19
|
+
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
|
|
22
|
+
/** Platform-aware Python launch candidates. An explicit config disables fallback. */
|
|
23
|
+
export function pythonCandidates(config, platform = process.platform) {
|
|
24
|
+
if (config.pythonCmd) return [{ command: config.pythonCmd, prefixArgs: [] }];
|
|
25
|
+
if (platform === "win32") {
|
|
26
|
+
return [
|
|
27
|
+
{ command: "py", prefixArgs: ["-3"] },
|
|
28
|
+
{ command: "python", prefixArgs: [] },
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
return [
|
|
32
|
+
{ command: "python3", prefixArgs: [] },
|
|
33
|
+
{ command: "python", prefixArgs: [] },
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Run a project Trellis script with bounded time and output. */
|
|
38
|
+
export async function runTrellisScript(
|
|
39
|
+
config,
|
|
40
|
+
root,
|
|
41
|
+
sessionId,
|
|
42
|
+
scriptArgs,
|
|
43
|
+
dependencies = {},
|
|
44
|
+
) {
|
|
45
|
+
const execute = dependencies.execFile ?? execFileAsync;
|
|
46
|
+
const platform = dependencies.platform ?? process.platform;
|
|
47
|
+
const signal = dependencies.signal;
|
|
48
|
+
const contextKey = dshContextKey(sessionId);
|
|
49
|
+
const env = {
|
|
50
|
+
...process.env,
|
|
51
|
+
...(contextKey
|
|
52
|
+
? {
|
|
53
|
+
TRELLIS_CONTEXT_ID: contextKey,
|
|
54
|
+
DSH_TRELLIS_CONTEXT_ID: contextKey,
|
|
55
|
+
DSH_SHELL: "1",
|
|
56
|
+
DSH_SESSION_ID: sessionId,
|
|
57
|
+
}
|
|
58
|
+
: {}),
|
|
59
|
+
};
|
|
60
|
+
const script = join(root, ".trellis", "scripts", "task.py");
|
|
61
|
+
const candidates = pythonCandidates(config, platform);
|
|
62
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
63
|
+
const args = [...candidate.prefixArgs, script, ...scriptArgs];
|
|
64
|
+
try {
|
|
65
|
+
const { stdout, stderr } = await execute(candidate.command, args, {
|
|
66
|
+
cwd: root,
|
|
67
|
+
env,
|
|
68
|
+
windowsHide: true,
|
|
69
|
+
timeout: 15_000,
|
|
70
|
+
maxBuffer: 256 * 1024,
|
|
71
|
+
...(signal ? { signal } : {}),
|
|
72
|
+
});
|
|
73
|
+
const text = `${stdout}${stderr ? `\n${stderr}` : ""}`.trim();
|
|
74
|
+
return { kind: "success", text };
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (signal?.aborted || error?.name === "AbortError") {
|
|
77
|
+
return { kind: "error", text: "Trellis command cancelled." };
|
|
78
|
+
}
|
|
79
|
+
const missing = error?.code === "ENOENT";
|
|
80
|
+
if (missing && index < candidates.length - 1) continue;
|
|
81
|
+
const attempted = candidates
|
|
82
|
+
.slice(0, index + 1)
|
|
83
|
+
.map(({ command, prefixArgs }) => [command, ...prefixArgs].join(" "))
|
|
84
|
+
.join(", ");
|
|
85
|
+
const message = missing
|
|
86
|
+
? `Python command not found (tried: ${attempted}). Set the plugin's pythonCmd config to a Python 3 executable.`
|
|
87
|
+
: `Trellis script failed via ${[candidate.command, ...candidate.prefixArgs].join(" ")}: ${error?.message ?? String(error)}`;
|
|
88
|
+
return { kind: "error", text: message };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
kind: "error",
|
|
93
|
+
text: "No Python command candidates are configured.",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Register the /trellis command family.
|
|
99
|
+
* @param {object} ctx - cordis context exposing `ctx.commands`.
|
|
100
|
+
* @param {object} resolved - normalized plugin config.
|
|
101
|
+
* @returns {() => void} disposer.
|
|
102
|
+
*/
|
|
103
|
+
export function registerCommands(ctx, resolved, dependencies = {}) {
|
|
104
|
+
const fs = dependencies.fs ?? nodeFs;
|
|
105
|
+
const execute = dependencies.execFile ?? execFileAsync;
|
|
106
|
+
const platform = dependencies.platform ?? process.platform;
|
|
107
|
+
const disposers = [];
|
|
108
|
+
|
|
109
|
+
const withoutInput = (invocation, fn) => {
|
|
110
|
+
const rawInput = invocation.rawInput ?? "";
|
|
111
|
+
const attachments = invocation.attachments ?? [];
|
|
112
|
+
if (rawInput.trim() !== "" || attachments.length > 0) {
|
|
113
|
+
return {
|
|
114
|
+
kind: "error",
|
|
115
|
+
text: "This Trellis command does not accept arguments or image attachments.",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return fn();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const withProject = async (invocation, fn) => {
|
|
122
|
+
const cwd = invocation.agent?.session?.header?.cwd ?? process.cwd();
|
|
123
|
+
const root = await findProjectRoot(cwd, resolved.projectRootMarkers, fs);
|
|
124
|
+
if (root === null) {
|
|
125
|
+
return {
|
|
126
|
+
kind: "error",
|
|
127
|
+
text: "No project root found from the configured markers.",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const workflow = join(root, ".trellis", "workflow.md");
|
|
131
|
+
const taskScript = join(root, ".trellis", "scripts", "task.py");
|
|
132
|
+
if (!(await fs.exists(workflow)) || !(await fs.exists(taskScript))) {
|
|
133
|
+
return {
|
|
134
|
+
kind: "error",
|
|
135
|
+
text: "No Trellis project found (expected .trellis/workflow.md and .trellis/scripts/task.py).",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const sessionId = invocation.agent?.session?.header?.id ?? "";
|
|
139
|
+
return fn(root, sessionId, invocation.signal);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
disposers.push(
|
|
143
|
+
ctx.commands.register({
|
|
144
|
+
name: "trellis-status",
|
|
145
|
+
description: "Show the Trellis active task and git status.",
|
|
146
|
+
// DSH rc.8 records command lifecycle events. These commands have no
|
|
147
|
+
// payload of their own, so omit empty/invalid input from the durable log.
|
|
148
|
+
recordInput: false,
|
|
149
|
+
handler: (invocation) =>
|
|
150
|
+
withoutInput(invocation, () =>
|
|
151
|
+
withProject(invocation, async (root, sessionId, signal) => {
|
|
152
|
+
const task = await runTrellisScript(
|
|
153
|
+
resolved,
|
|
154
|
+
root,
|
|
155
|
+
sessionId,
|
|
156
|
+
["current", "--source"],
|
|
157
|
+
{ execFile: execute, platform, signal },
|
|
158
|
+
);
|
|
159
|
+
if (signal?.aborted) return task;
|
|
160
|
+
let git = "";
|
|
161
|
+
try {
|
|
162
|
+
const { stdout } = await execute(
|
|
163
|
+
"git",
|
|
164
|
+
["status", "--short", "--branch"],
|
|
165
|
+
{
|
|
166
|
+
cwd: root,
|
|
167
|
+
windowsHide: true,
|
|
168
|
+
timeout: 10_000,
|
|
169
|
+
maxBuffer: 128 * 1024,
|
|
170
|
+
...(signal ? { signal } : {}),
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
git = `\n\nGit status:\n${stdout.trim()}`;
|
|
174
|
+
} catch {
|
|
175
|
+
git = "";
|
|
176
|
+
}
|
|
177
|
+
const hint =
|
|
178
|
+
task.kind === "success"
|
|
179
|
+
? `\n\nSession rituals: type /trellis-start (start), /trellis-continue (resume), /trellis-finish-work (skill wrap-up).`
|
|
180
|
+
: "";
|
|
181
|
+
return { kind: task.kind, text: `${task.text}${git}${hint}` };
|
|
182
|
+
}),
|
|
183
|
+
),
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
disposers.push(
|
|
188
|
+
ctx.commands.register({
|
|
189
|
+
name: "trellis-finish",
|
|
190
|
+
description:
|
|
191
|
+
"Inspect the active task and print the safe wrap-up checklist.",
|
|
192
|
+
recordInput: false,
|
|
193
|
+
handler: (invocation) =>
|
|
194
|
+
withoutInput(invocation, () =>
|
|
195
|
+
withProject(invocation, async (root, sessionId, signal) => {
|
|
196
|
+
const result = await runTrellisScript(
|
|
197
|
+
resolved,
|
|
198
|
+
root,
|
|
199
|
+
sessionId,
|
|
200
|
+
["current", "--source"],
|
|
201
|
+
{ execFile: execute, platform, signal },
|
|
202
|
+
);
|
|
203
|
+
if (signal?.aborted) return result;
|
|
204
|
+
const checklist =
|
|
205
|
+
'Wrap-up checklist (this command did not clear or archive anything):\n 1. Commit this task\'s changes (workflow.md Phase 3.4; do not push).\n 2. Type /trellis-finish-work so the skill can archive the task before the pointer is removed and then record the session journal.\n\nIf you must do it manually, archive first with the configured Python 3 runtime: .trellis/scripts/task.py archive <task-name>; then run .trellis/scripts/add_session.py --title "..." --commit <hash> --summary "...".';
|
|
206
|
+
return { kind: result.kind, text: `${result.text}\n\n${checklist}` };
|
|
207
|
+
}),
|
|
208
|
+
),
|
|
209
|
+
}),
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
return () => {
|
|
213
|
+
for (const dispose of disposers) dispose();
|
|
214
|
+
};
|
|
215
|
+
}
|
package/lib/config.js
CHANGED
|
@@ -1,45 +1,77 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* dsh-trellis plugin configuration (Schemastery).
|
|
3
|
-
*
|
|
4
|
-
* @module dsh-trellis/config
|
|
5
|
-
*/
|
|
6
|
-
import z from "@deepseek-ai/schemastery";
|
|
7
|
-
|
|
8
|
-
export const Config = z.object({
|
|
9
|
-
/**
|
|
10
|
-
enabled: z
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
1
|
+
/**
|
|
2
|
+
* dsh-trellis plugin configuration (Schemastery).
|
|
3
|
+
*
|
|
4
|
+
* @module dsh-trellis/config
|
|
5
|
+
*/
|
|
6
|
+
import z from "@deepseek-ai/schemastery";
|
|
7
|
+
|
|
8
|
+
export const Config = z.object({
|
|
9
|
+
/** Runtime master switch; the rc.8 settings namespace remains available for re-enabling. */
|
|
10
|
+
enabled: z
|
|
11
|
+
.boolean()
|
|
12
|
+
.default(true)
|
|
13
|
+
.description(
|
|
14
|
+
"Enable Trellis breadcrumbs, commands, session facts, and the wait tool for this profile.",
|
|
15
|
+
),
|
|
16
|
+
/** UTF-8 byte budget for the injected breadcrumb text. 0 disables injection. */
|
|
17
|
+
maxBytes: z
|
|
18
|
+
.number()
|
|
19
|
+
.step(1)
|
|
20
|
+
.min(0)
|
|
21
|
+
.default(4096)
|
|
22
|
+
.description(
|
|
23
|
+
"Maximum UTF-8 bytes in a workflow-state breadcrumb; 0 disables breadcrumbs.",
|
|
24
|
+
),
|
|
25
|
+
/** Directory markers that identify a project root (walked upward from the session cwd). */
|
|
26
|
+
projectRootMarkers: z
|
|
27
|
+
.array(z.string())
|
|
28
|
+
.default([".git"])
|
|
29
|
+
.description(
|
|
30
|
+
"Directory entries used while walking upward to find the project root.",
|
|
31
|
+
),
|
|
32
|
+
/** Standalone word (case-insensitive) in the user prompt that skips breadcrumb injection for that turn. Empty disables. */
|
|
33
|
+
skipKeyword: z
|
|
34
|
+
.string()
|
|
35
|
+
.default("no-trellis")
|
|
36
|
+
.description(
|
|
37
|
+
"Standalone prompt keyword that skips one breadcrumb injection; empty disables the escape hatch.",
|
|
38
|
+
),
|
|
39
|
+
/** Python executable used by /trellis commands. Empty selects a platform-aware fallback chain. */
|
|
40
|
+
pythonCmd: z
|
|
41
|
+
.string()
|
|
42
|
+
.default("")
|
|
43
|
+
.description(
|
|
44
|
+
"Python 3 executable for Trellis scripts; empty selects a platform-aware launcher chain.",
|
|
45
|
+
),
|
|
46
|
+
/** Register the deterministic /trellis-status and read-only /trellis-finish commands. */
|
|
47
|
+
commandsEnabled: z
|
|
48
|
+
.boolean()
|
|
49
|
+
.default(true)
|
|
50
|
+
.description(
|
|
51
|
+
"Register /trellis-status and the read-only /trellis-finish helper.",
|
|
52
|
+
),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Normalized runtime configuration.
|
|
57
|
+
* @param {Partial<Record<string, unknown>>} config
|
|
58
|
+
* @returns {{
|
|
59
|
+
* enabled: boolean,
|
|
60
|
+
* maxBytes: number,
|
|
61
|
+
* projectRootMarkers: string[],
|
|
62
|
+
* skipKeyword: string,
|
|
63
|
+
* pythonCmd: string,
|
|
64
|
+
* commandsEnabled: boolean,
|
|
65
|
+
* }}
|
|
66
|
+
*/
|
|
67
|
+
export function resolveConfig(config) {
|
|
68
|
+
return {
|
|
69
|
+
enabled: config.enabled !== false,
|
|
70
|
+
maxBytes: config.maxBytes ?? 4096,
|
|
71
|
+
projectRootMarkers: config.projectRootMarkers ?? [".git"],
|
|
72
|
+
skipKeyword: config.skipKeyword ?? "no-trellis",
|
|
73
|
+
pythonCmd:
|
|
74
|
+
typeof config.pythonCmd === "string" ? config.pythonCmd.trim() : "",
|
|
75
|
+
commandsEnabled: config.commandsEnabled !== false,
|
|
76
|
+
};
|
|
77
|
+
}
|