copilot-operator 0.1.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.
Files changed (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +556 -0
  3. package/dist/src/api/app.module.js +18 -0
  4. package/dist/src/api/dataAcl.js +109 -0
  5. package/dist/src/api/folderPicker.js +110 -0
  6. package/dist/src/api/main.js +132 -0
  7. package/dist/src/api/operator.controller.js +975 -0
  8. package/dist/src/api/operator.service.js +1971 -0
  9. package/dist/src/api/saveToDesktop.js +157 -0
  10. package/dist/src/api/security.js +225 -0
  11. package/dist/src/api/settings.js +57 -0
  12. package/dist/src/cli.js +531 -0
  13. package/dist/src/config/layout.js +66 -0
  14. package/dist/src/config/lockedPolicy.js +176 -0
  15. package/dist/src/config/schema.js +487 -0
  16. package/dist/src/context/contextFiles.js +295 -0
  17. package/dist/src/context/desktopMirror.js +113 -0
  18. package/dist/src/context/projectMirror.js +364 -0
  19. package/dist/src/exec/authorizer.js +61 -0
  20. package/dist/src/exec/checks.js +285 -0
  21. package/dist/src/exec/confinement.js +224 -0
  22. package/dist/src/exec/dangerous.js +161 -0
  23. package/dist/src/exec/environment.js +80 -0
  24. package/dist/src/exec/isolation.js +166 -0
  25. package/dist/src/exec/network.js +242 -0
  26. package/dist/src/exec/policy.js +201 -0
  27. package/dist/src/exec/policyManifest.js +84 -0
  28. package/dist/src/exec/processes.js +329 -0
  29. package/dist/src/exec/programs.js +290 -0
  30. package/dist/src/exec/redaction.js +93 -0
  31. package/dist/src/exec/reportFile.js +154 -0
  32. package/dist/src/exec/runner.js +245 -0
  33. package/dist/src/exec/scriptFiles.js +81 -0
  34. package/dist/src/exec/shellExecuteTrap.js +221 -0
  35. package/dist/src/exec/shells.js +298 -0
  36. package/dist/src/exec/stepEnv.js +72 -0
  37. package/dist/src/exec/winps.js +17 -0
  38. package/dist/src/exec/workDir.js +94 -0
  39. package/dist/src/log/runLog.js +43 -0
  40. package/dist/src/orchestrator/derivedChecks.js +95 -0
  41. package/dist/src/orchestrator/review.js +590 -0
  42. package/dist/src/orchestrator/taskRunner.js +1582 -0
  43. package/dist/src/plan/brief.js +1785 -0
  44. package/dist/src/plan/importPlan.js +202 -0
  45. package/dist/src/plan/schema.js +483 -0
  46. package/dist/src/plan/script.js +1012 -0
  47. package/dist/src/plan/systemGuide.js +1851 -0
  48. package/dist/src/protocol/parser.js +224 -0
  49. package/dist/src/protocol/replySchema.js +207 -0
  50. package/dist/src/protocol/reporter.js +75 -0
  51. package/dist/src/protocol/reviewSchema.js +205 -0
  52. package/dist/src/session/compose.js +67 -0
  53. package/dist/src/session/debugExport.js +165 -0
  54. package/dist/src/session/events.js +34 -0
  55. package/dist/src/session/exportRecord.js +261 -0
  56. package/dist/src/session/exports.js +484 -0
  57. package/dist/src/session/model.js +22 -0
  58. package/dist/src/session/retention.js +34 -0
  59. package/dist/src/session/runName.js +36 -0
  60. package/dist/src/session/store.js +440 -0
  61. package/dist/src/session/story.js +198 -0
  62. package/dist/src/transport/acceptance.js +34 -0
  63. package/dist/src/transport/chatSession.js +73 -0
  64. package/dist/src/transport/copilotTransport.js +1208 -0
  65. package/dist/src/transport/edgeCrash.js +59 -0
  66. package/dist/src/transport/locators.js +261 -0
  67. package/dist/src/transport/profileLock.js +102 -0
  68. package/dist/src/util/pacing.js +89 -0
  69. package/dist/src/vcs/commitHygiene.js +102 -0
  70. package/dist/src/vcs/git.js +286 -0
  71. package/dist/src/vcs/taskVcs.js +343 -0
  72. package/dist/web/404.html +15 -0
  73. package/dist/web/_next/static/chunks/12.f1f4d35b52633e8d.js +1 -0
  74. package/dist/web/_next/static/chunks/131-bae98f790a541679.js +1 -0
  75. package/dist/web/_next/static/chunks/197-f7c33a0114fc3db3.js +1 -0
  76. package/dist/web/_next/static/chunks/489.158bbe303a595fba.js +1 -0
  77. package/dist/web/_next/static/chunks/643-34b9f66a6c317c4a.js +1 -0
  78. package/dist/web/_next/static/chunks/867-03b7cac8f79896c3.js +1 -0
  79. package/dist/web/_next/static/chunks/955-63de06e182d98949.js +1 -0
  80. package/dist/web/_next/static/chunks/app/_not-found/page-0d0d8e7e62efca12.js +1 -0
  81. package/dist/web/_next/static/chunks/app/appearance/page-501842e7aeac7f6b.js +1 -0
  82. package/dist/web/_next/static/chunks/app/defaults/page-ed858127cbdfb4ab.js +1 -0
  83. package/dist/web/_next/static/chunks/app/history/page-bad4f3e89b485719.js +1 -0
  84. package/dist/web/_next/static/chunks/app/import/page-db1f5f1ab2f5cad1.js +1 -0
  85. package/dist/web/_next/static/chunks/app/layout-72251c52cc54f95e.js +1 -0
  86. package/dist/web/_next/static/chunks/app/level1/page-cf3e50cf64fecf4f.js +1 -0
  87. package/dist/web/_next/static/chunks/app/page-6fd16e5c8cf3b20f.js +1 -0
  88. package/dist/web/_next/static/chunks/app/presets/page-951e78b80e0e22e6.js +1 -0
  89. package/dist/web/_next/static/chunks/app/sessions/view/page-f2e63618097d7221.js +1 -0
  90. package/dist/web/_next/static/chunks/app/system/page-44e7954c0e48f4ba.js +1 -0
  91. package/dist/web/_next/static/chunks/c7879cf7-b5ab1053c1d9a2e7.js +1 -0
  92. package/dist/web/_next/static/chunks/framework-9ac6a346bd42cedd.js +1 -0
  93. package/dist/web/_next/static/chunks/main-6be4444e2d667e41.js +1 -0
  94. package/dist/web/_next/static/chunks/main-app-e3a5f713ba31557e.js +1 -0
  95. package/dist/web/_next/static/chunks/pages/_app-32d20d5a04949d29.js +1 -0
  96. package/dist/web/_next/static/chunks/pages/_error-abbab53f25ea29b0.js +1 -0
  97. package/dist/web/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  98. package/dist/web/_next/static/chunks/webpack-0f31b926d9a9c5a4.js +1 -0
  99. package/dist/web/_next/static/css/d77735cdc9020a86.css +1 -0
  100. package/dist/web/_next/static/u8rZNwh4d3n-HGJnfZ72Y/_buildManifest.js +1 -0
  101. package/dist/web/_next/static/u8rZNwh4d3n-HGJnfZ72Y/_ssgManifest.js +1 -0
  102. package/dist/web/appearance.html +15 -0
  103. package/dist/web/appearance.txt +26 -0
  104. package/dist/web/defaults.html +15 -0
  105. package/dist/web/defaults.txt +26 -0
  106. package/dist/web/history.html +15 -0
  107. package/dist/web/history.txt +26 -0
  108. package/dist/web/import.html +15 -0
  109. package/dist/web/import.txt +26 -0
  110. package/dist/web/index.html +15 -0
  111. package/dist/web/index.txt +26 -0
  112. package/dist/web/level1.html +15 -0
  113. package/dist/web/level1.txt +26 -0
  114. package/dist/web/presets.html +18 -0
  115. package/dist/web/presets.txt +26 -0
  116. package/dist/web/sessions/view.html +15 -0
  117. package/dist/web/sessions/view.txt +26 -0
  118. package/dist/web/system.html +15 -0
  119. package/dist/web/system.txt +26 -0
  120. package/package.json +111 -0
  121. package/prompts/level1.md +535 -0
  122. package/prompts/organisation.bg.md +44 -0
  123. package/prompts/organisation.en.md +44 -0
  124. package/prompts/persona.bg.md +17 -0
  125. package/prompts/persona.en.md +17 -0
  126. package/prompts/review1.md +277 -0
  127. package/prompts/work.bg.md +19 -0
  128. package/prompts/work.en.md +19 -0
@@ -0,0 +1,975 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Body, Controller, Delete, Get, Param, Post, Put, Query, Res, Sse, NotFoundException, BadRequestException } from '@nestjs/common';
14
+ import { Observable } from 'rxjs';
15
+ import { OperatorService } from './operator.service.js';
16
+ function fail(e) {
17
+ throw new BadRequestException(e.message);
18
+ }
19
+ /**
20
+ * A `content-disposition` header a session name cannot break.
21
+ *
22
+ * Header values are ASCII. A session called "тест4" produced a file name with Cyrillic in it,
23
+ * and Node refused to send the header at all, so the download failed with an error that said
24
+ * nothing about names. The fix is the standard pair: an ASCII fallback for anything old, and
25
+ * `filename*` with the real name percent-encoded for every current browser.
26
+ */
27
+ /** The three kinds, checked here so a path cannot name a file of its own choosing. */
28
+ function asContextKind(kind) {
29
+ if (kind !== 'organisation' && kind !== 'persona' && kind !== 'work') {
30
+ throw new BadRequestException('kind must be organisation, persona or work');
31
+ }
32
+ return kind;
33
+ }
34
+ function contentDisposition(fileName) {
35
+ const ascii = fileName.replace(/[^\x20-\x7e]/g, '_').replace(/["\\]/g, '_');
36
+ return `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(fileName)}`;
37
+ }
38
+ let OperatorController = class OperatorController {
39
+ ops;
40
+ constructor(ops) {
41
+ this.ops = ops;
42
+ }
43
+ health() {
44
+ return { ok: true, time: new Date().toISOString() };
45
+ }
46
+ doctor() {
47
+ return this.ops.doctor();
48
+ }
49
+ // --- settings ---------------------------------------------------------------------------
50
+ async settings() {
51
+ const [raw, defaults, resolved] = await Promise.all([this.ops.settings.raw(), this.ops.settings.defaults(), this.ops.settings.load()]);
52
+ return { raw, defaults, resolved: resolved.resolved };
53
+ }
54
+ async saveSettings(body) {
55
+ await this.ops.settings.save(body).catch(fail);
56
+ return { ok: true };
57
+ }
58
+ // --- level 1 ----------------------------------------------------------------------------
59
+ level1() {
60
+ return this.ops.getLevel1();
61
+ }
62
+ async setLevel1(body) {
63
+ if (typeof body?.content !== 'string' || body.content.trim().length < 100) {
64
+ throw new BadRequestException('Level 1 must be a real contract, not a few words.');
65
+ }
66
+ await this.ops.setLevel1(body.content);
67
+ return { ok: true };
68
+ }
69
+ resetLevel1() {
70
+ return this.ops.resetLevel1();
71
+ }
72
+ // --- level 2 presets --------------------------------------------------------------------
73
+ presets() {
74
+ return this.ops.listPresets();
75
+ }
76
+ savePreset(name, body) {
77
+ return this.ops.savePreset(name, body?.content ?? '').catch(fail);
78
+ }
79
+ async deletePreset(name) {
80
+ await this.ops.deletePreset(name);
81
+ return { ok: true };
82
+ }
83
+ // --- sessions ---------------------------------------------------------------------------
84
+ sessions() {
85
+ return this.ops.listSessions();
86
+ }
87
+ createSession(body) {
88
+ return this.ops.createSession(body?.name ?? '', body?.mirror).catch(fail);
89
+ }
90
+ async session(id) {
91
+ const s = await this.ops.getSession(id);
92
+ if (!s)
93
+ throw new NotFoundException();
94
+ return s;
95
+ }
96
+ /** Name, model, queue behaviour, files, version control and the independent review. */
97
+ updateSession(id, body) {
98
+ return this.ops.updateSession(id, body).catch(fail);
99
+ }
100
+ async deleteSession(id) {
101
+ await this.ops.deleteSession(id).catch(fail);
102
+ return { ok: true };
103
+ }
104
+ addTask(id, body) {
105
+ return this.ops.addTask(id, { title: body?.title ?? '', level2: body?.level2 ?? '', prompt: body?.prompt ?? '' }).catch(fail);
106
+ }
107
+ updateTask(id, taskId, body) {
108
+ return this.ops.updateTask(id, taskId, body).catch(fail);
109
+ }
110
+ async deleteTask(id, taskId) {
111
+ await this.ops.deleteTask(id, taskId).catch(fail);
112
+ return { ok: true };
113
+ }
114
+ /**
115
+ * Puts a finished task back in the queue, keeping the earlier attempt on the record.
116
+ *
117
+ * A body with `title`, `prompt` or `level2` edits the task on the way: the attempt that
118
+ * already ran keeps the text it ran with, and the next one uses the new text.
119
+ */
120
+ rerunTask(id, taskId, body) {
121
+ return this.ops.rerunTask(id, taskId, body ?? {}).catch(fail);
122
+ }
123
+ /** What going back to before this task would do. Changes nothing. */
124
+ restorePreview(id, taskId) {
125
+ return this.ops.restorePreview(id, taskId).catch(fail);
126
+ }
127
+ /** Does it: a new branch at the commit that task started from, checked out. */
128
+ restore(id, taskId) {
129
+ return this.ops.restore(id, taskId).catch(fail);
130
+ }
131
+ /** What starting the run again from this task would re-queue, and do to the code. */
132
+ restartPlan(id, taskId) {
133
+ return this.ops.restartPlan(id, taskId).catch(fail);
134
+ }
135
+ /** Restores the code, queues this task and everything after it, and starts the run again. */
136
+ restartFrom(id, taskId, body) {
137
+ return this.ops.restartFrom(id, taskId, body ?? {}).catch(fail);
138
+ }
139
+ async taskLog(id, taskId, res, run) {
140
+ const text = await this.ops.taskLog(id, taskId, run);
141
+ if (text === null) {
142
+ res.status(404).send('no log yet');
143
+ return;
144
+ }
145
+ res.type('text/plain; charset=utf-8').send(text);
146
+ }
147
+ /**
148
+ * The same log, saved to the Desktop and shown in Explorer, which is what the operator
149
+ * actually wants it for. The GET above stays as it is: it is where this falls back to when
150
+ * the machine refuses to write the file, or when there is no Desktop to write it to.
151
+ */
152
+ async saveTaskLog(id, taskId, run) {
153
+ const saved = await this.ops.saveTaskLog(id, taskId, run).catch(fail);
154
+ if (!saved)
155
+ throw new NotFoundException('This task has not produced a log yet.');
156
+ return saved;
157
+ }
158
+ /** The attempt as a story: what was sent, answered, run and how it ended. `run` picks an earlier attempt. */
159
+ async taskStory(id, taskId, run) {
160
+ const story = await this.ops.taskStory(id, taskId, run);
161
+ if (!story)
162
+ throw new NotFoundException('This task has not run yet, or that attempt is not its own.');
163
+ return story;
164
+ }
165
+ taskFiles(id, taskId, run) {
166
+ return this.ops.taskFiles(id, taskId, run);
167
+ }
168
+ async taskFile(id, taskId, kind, name, res, run) {
169
+ if (!['reports', 'artifacts', 'replies'].includes(kind)) {
170
+ res.status(400).send('bad kind');
171
+ return;
172
+ }
173
+ const text = await this.ops.taskFile(id, taskId, kind, name, run);
174
+ if (text === null) {
175
+ res.status(404).send('not found');
176
+ return;
177
+ }
178
+ res.type('text/plain; charset=utf-8').send(text);
179
+ }
180
+ /** A task's own file, saved to the Desktop and shown in Explorer, exactly as its log is. */
181
+ async saveTaskFile(id, taskId, kind, name, run) {
182
+ if (!['reports', 'artifacts', 'replies'].includes(kind))
183
+ throw new BadRequestException('kind must be reports, artifacts or replies');
184
+ const saved = await this.ops.saveTaskFile(id, taskId, kind, name, run).catch(fail);
185
+ if (!saved)
186
+ throw new NotFoundException('That file is not there.');
187
+ return saved;
188
+ }
189
+ /**
190
+ * Downloads the record of selected tasks.
191
+ *
192
+ * `tasks` is a comma-separated list of task ids, or absent for every task that has run.
193
+ * `variant` is `full` for the whole conversation, or `outcome` for the first and the last
194
+ * message only, which is the expected-and-actual pair.
195
+ */
196
+ async exportTasks(id, res, tasks, variant) {
197
+ const ids = (tasks ?? '').split(',').map((x) => x.trim()).filter(Boolean);
198
+ const kind = variant === 'full' ? 'full' : 'outcome';
199
+ try {
200
+ const { fileName, content } = await this.ops.exportTasks(id, ids, kind);
201
+ res.type('text/plain; charset=utf-8');
202
+ res.setHeader('content-disposition', contentDisposition(fileName));
203
+ res.send(content);
204
+ }
205
+ catch (e) {
206
+ res.status(400).send(e.message);
207
+ }
208
+ }
209
+ /**
210
+ * Everything that happened across several sessions, as one JSON file.
211
+ *
212
+ * `sessions` is a comma-separated list of ids; leaving it out means the sessions of the last
213
+ * batch. Meant for handing to somebody — or something — that has to work out why a run went
214
+ * the way it did.
215
+ */
216
+ async debugExport(res, sessions) {
217
+ const ids = (sessions ?? '').split(',').map((x) => x.trim()).filter(Boolean);
218
+ try {
219
+ const { fileName, content } = await this.ops.debugExport(ids);
220
+ res.type('application/json; charset=utf-8');
221
+ res.setHeader('content-disposition', contentDisposition(fileName));
222
+ res.send(content);
223
+ }
224
+ catch (e) {
225
+ res.status(400).send(e.message);
226
+ }
227
+ }
228
+ /**
229
+ * All three views of a set of tasks the operator ticked, as one file.
230
+ *
231
+ * A POST rather than a GET, which makes it the odd one out among the exports and is the right
232
+ * odd one out: the others name a run, a session or a task and fit in a query string, while this
233
+ * names every task that was chosen, and a register with sixty finished tasks in it would put a
234
+ * selection past what a URL can carry. The browser saves the body with a download link made
235
+ * from a blob, so nothing about the operator's side of it changes.
236
+ */
237
+ async exportBundle(res, body) {
238
+ const pairs = (body?.tasks ?? [])
239
+ .map((x) => ({ sessionId: (x?.sessionId ?? '').trim(), taskId: (x?.taskId ?? '').trim() }))
240
+ .filter((x) => x.sessionId && x.taskId);
241
+ try {
242
+ const { fileName, content } = await this.ops.exportBundle(pairs);
243
+ res.type('application/json; charset=utf-8');
244
+ res.setHeader('content-disposition', contentDisposition(fileName));
245
+ res.send(content);
246
+ }
247
+ catch (e) {
248
+ res.status(400).send(e.message);
249
+ }
250
+ }
251
+ /**
252
+ * One of the three JSON views of a task, a session or a run: `plan` (what was asked, in the
253
+ * format that imports again), `domain` (what happened to the work) or `bot` (what the runner
254
+ * did). Exactly one of `run`, `session` or `session`+`task` names the scope.
255
+ */
256
+ async exportView(kind, res, run, session, task) {
257
+ if (kind !== 'plan' && kind !== 'domain' && kind !== 'bot') {
258
+ res.status(400).send('kind must be plan, domain or bot');
259
+ return;
260
+ }
261
+ try {
262
+ const { fileName, content } = await this.ops.exportView(kind, { runId: run?.trim() || undefined, sessionId: session?.trim() || undefined, taskId: task?.trim() || undefined });
263
+ res.type('application/json; charset=utf-8');
264
+ res.setHeader('content-disposition', contentDisposition(fileName));
265
+ res.send(content);
266
+ }
267
+ catch (e) {
268
+ res.status(400).send(e.message);
269
+ }
270
+ }
271
+ // --- run control ------------------------------------------------------------------------
272
+ start(id, body) {
273
+ return this.ops.start(id, body?.mode === 'unattended' ? 'unattended' : 'confirm', body?.name);
274
+ }
275
+ stop(id) {
276
+ return this.ops.stop(id);
277
+ }
278
+ // --- running several sessions in turn ------------------------------------------------------
279
+ /** The batch in progress, or the last one that ran. Null when none ever has. */
280
+ batch() {
281
+ return this.ops.batchState();
282
+ }
283
+ /**
284
+ * Runs the queued tasks of several sessions, one after another, in the order given.
285
+ *
286
+ * `onFailure` is about the sessions, not the tasks inside them: `stop` gives up on the rest
287
+ * once a session fails, `continue` works through all of them.
288
+ */
289
+ /**
290
+ * What this run would be called if nobody typed anything, so the page can show it first.
291
+ *
292
+ * The same answer `startBatch` would reach on its own, asked before the fact rather than after,
293
+ * because a name the operator can see and correct is worth more than a name that appears in the
294
+ * register once it is too late to argue with.
295
+ */
296
+ suggestRunName(sessions) {
297
+ const ids = (sessions ?? '').split(',').map((x) => x.trim()).filter(Boolean);
298
+ return this.ops.suggestRunName(ids).then((name) => ({ name }));
299
+ }
300
+ startBatch(body) {
301
+ if (!Array.isArray(body?.sessionIds))
302
+ throw new BadRequestException('sessionIds must be a list of session ids');
303
+ return this.ops
304
+ .startBatch(body.sessionIds, body?.mode === 'unattended' ? 'unattended' : 'confirm', body?.onFailure === 'continue' ? 'continue' : 'stop',
305
+ // Absent or empty means every session keeps the model it already has, which is not the
306
+ // same as "no model": an empty string on a session means "leave the chat alone".
307
+ body?.model,
308
+ // The same for the review: absent means each session keeps whatever it is set to.
309
+ body?.reviewModel, body?.name)
310
+ .catch(fail);
311
+ }
312
+ stopBatch() {
313
+ return this.ops.stopBatch();
314
+ }
315
+ /**
316
+ * Holds the run after the task that is running finishes, rather than after its current step.
317
+ *
318
+ * The pair of them are one switch from the page's point of view, so they are one route each
319
+ * rather than one route with a flag: a request that says what it wants cannot be misread.
320
+ */
321
+ pauseBatch() {
322
+ return this.ops.pauseBatch();
323
+ }
324
+ resumeBatch() {
325
+ return this.ops.resumeBatch();
326
+ }
327
+ // --- plans ---------------------------------------------------------------------------------
328
+ /**
329
+ * The text the operator pastes into a chat model to have a plan written.
330
+ *
331
+ * One text per language and nothing else to choose. It used to be assembled from answers
332
+ * given on the import page — version control on or off, which folder — and those are now
333
+ * questions the brief tells the model to ask, because the model is the one in the
334
+ * conversation and the answers belong to a session rather than to the whole document.
335
+ */
336
+ async planBrief(lang) {
337
+ return await this.ops.planBrief({ lang: lang ?? 'en' });
338
+ }
339
+ // --- the operator's own two texts for the plan persona -------------------------------
340
+ /**
341
+ * `organisation` is how the company works and where the projects are, which changes rarely;
342
+ * `work` is what this group of tasks is about, which changes whenever the work does.
343
+ */
344
+ context(kind, lang) {
345
+ return this.ops.getContext(asContextKind(kind), lang ?? 'en');
346
+ }
347
+ async setContext(kind, body) {
348
+ if (typeof body?.content !== 'string')
349
+ throw new BadRequestException('content must be text');
350
+ await this.ops.setContext(asContextKind(kind), body.content);
351
+ return { ok: true };
352
+ }
353
+ resetContext(kind, lang) {
354
+ return this.ops.resetContext(asContextKind(kind), lang ?? 'en');
355
+ }
356
+ /** Checks a pasted plan without importing anything, and says what it would duplicate. */
357
+ checkPlan(body) {
358
+ return this.ops.checkPlan(body?.text ?? '').catch(fail);
359
+ }
360
+ /**
361
+ * Creates the sessions and tasks a plan describes, and starts nothing.
362
+ *
363
+ * A plan that does not validate comes back as 200 with `ok: false` rather than as an error,
364
+ * because the list of what is wrong is the useful part of that answer and the UI shows it
365
+ * to the operator to hand back to the chat.
366
+ */
367
+ importPlan(body) {
368
+ return this.ops.importPlan(body?.text ?? '').catch(fail);
369
+ }
370
+ events(id) {
371
+ return this.ops.recentEvents(id);
372
+ }
373
+ /** Live events as server-sent events. The browser's EventSource reconnects on its own. */
374
+ stream(id) {
375
+ return new Observable((subscriber) => {
376
+ for (const e of this.ops.recentEvents(id))
377
+ subscriber.next({ data: JSON.stringify(e) });
378
+ const off = this.ops.subscribe(id, (e) => subscriber.next({ data: JSON.stringify(e) }));
379
+ const keepAlive = setInterval(() => subscriber.next({ data: JSON.stringify({ type: 'ping', at: new Date().toISOString() }) }), 25_000);
380
+ return () => {
381
+ off();
382
+ clearInterval(keepAlive);
383
+ };
384
+ });
385
+ }
386
+ // --- approvals --------------------------------------------------------------------------
387
+ approvals(session) {
388
+ return this.ops.pendingApprovals(session);
389
+ }
390
+ decide(id, body) {
391
+ if (!['run', 'skip', 'abort', 'run-all'].includes(body?.action)) {
392
+ throw new BadRequestException('action must be run, run-all, skip or abort');
393
+ }
394
+ return this.ops.decide(id, body.action);
395
+ }
396
+ /** Turns asking on or off in the middle of a run. */
397
+ setMode(id, body) {
398
+ if (body?.mode !== 'confirm' && body?.mode !== 'unattended') {
399
+ throw new BadRequestException('mode must be confirm or unattended');
400
+ }
401
+ return this.ops.setRunMode(id, body.mode);
402
+ }
403
+ /**
404
+ * Is anything running? Answered from memory, so it is safe to ask from every page.
405
+ */
406
+ activity() {
407
+ return this.ops.activity();
408
+ }
409
+ // --- the project being worked on -----------------------------------------------------------
410
+ /** The folder new sessions start pointed at, and whether it can carry version control. */
411
+ project() {
412
+ return this.ops.project();
413
+ }
414
+ /** Stores it. A field left out is kept; an empty `rootDir` clears the default. */
415
+ setProject(body) {
416
+ return this.ops
417
+ .setProject({ rootDir: body?.rootDir, name: body?.name, others: body?.others, mirrorToDesktop: body?.mirrorToDesktop, mirror: body?.mirror })
418
+ .catch(fail);
419
+ }
420
+ /**
421
+ * Whether a folder can be used for version control at all, asked before the choice is made.
422
+ *
423
+ * Separate from the session's own preflight because that one only speaks when version
424
+ * control is already on, and the question here is whether it may be turned on.
425
+ */
426
+ repo(dir) {
427
+ const problem = this.ops.repoProblem(dir ?? '');
428
+ return problem ? { ok: false, problem } : { ok: true };
429
+ }
430
+ /** Can version control do its job in this session right now? */
431
+ vcsStatus(id) {
432
+ return this.ops.vcsStatus(id).catch(fail);
433
+ }
434
+ // --- the model picker ---------------------------------------------------------------------
435
+ /** The cached list. Returns null when the picker has never been read on this machine. */
436
+ models() {
437
+ return this.ops.models();
438
+ }
439
+ /**
440
+ * Re-reads the picker from the live chat. Slow on purpose: it opens the browser with the
441
+ * bot profile, so it cannot run while a session is running.
442
+ */
443
+ refreshModels() {
444
+ return this.ops.refreshModels().catch(fail);
445
+ }
446
+ /** The model new sessions start on. An empty name means "leave the chat alone". */
447
+ setDefaultModel(body) {
448
+ return this.ops.setDefaultModel(body?.model ?? '').catch(fail);
449
+ }
450
+ /** The model a new session's independent review runs on. An empty name means "the session's own". */
451
+ setDefaultReviewModel(body) {
452
+ return this.ops.setDefaultReviewModel(body?.model ?? '').catch(fail);
453
+ }
454
+ // --- the registry of every task -----------------------------------------------------------
455
+ tasks() {
456
+ return this.ops.taskRegistry();
457
+ }
458
+ // --- helpers for the UI -----------------------------------------------------------------
459
+ dirs(root, gitignore) {
460
+ if (!root)
461
+ throw new BadRequestException('root is required');
462
+ return this.ops.dirs(root, gitignore !== '0' && gitignore !== 'false');
463
+ }
464
+ /**
465
+ * Opens the machine's own folder dialog. A POST because it has a visible effect: a window
466
+ * appears on the operator's desktop and waits for them.
467
+ */
468
+ browseFolder(body) {
469
+ return this.ops.browseFolder(body?.start);
470
+ }
471
+ preview(body) {
472
+ if (!body?.rootDir?.trim())
473
+ throw new BadRequestException('rootDir is required');
474
+ return this.ops
475
+ .previewMirror({
476
+ rootDir: body.rootDir.trim(),
477
+ includeDirs: body.includeDirs ?? [],
478
+ excludeDirs: body.excludeDirs ?? [],
479
+ respectGitignore: body.respectGitignore ?? true,
480
+ includeEnvFiles: body.includeEnvFiles ?? false,
481
+ })
482
+ .catch(fail);
483
+ }
484
+ };
485
+ __decorate([
486
+ Get('health'),
487
+ __metadata("design:type", Function),
488
+ __metadata("design:paramtypes", []),
489
+ __metadata("design:returntype", Object)
490
+ ], OperatorController.prototype, "health", null);
491
+ __decorate([
492
+ Get('doctor'),
493
+ __metadata("design:type", Function),
494
+ __metadata("design:paramtypes", []),
495
+ __metadata("design:returntype", Promise)
496
+ ], OperatorController.prototype, "doctor", null);
497
+ __decorate([
498
+ Get('settings'),
499
+ __metadata("design:type", Function),
500
+ __metadata("design:paramtypes", []),
501
+ __metadata("design:returntype", Promise)
502
+ ], OperatorController.prototype, "settings", null);
503
+ __decorate([
504
+ Put('settings'),
505
+ __param(0, Body()),
506
+ __metadata("design:type", Function),
507
+ __metadata("design:paramtypes", [Object]),
508
+ __metadata("design:returntype", Promise)
509
+ ], OperatorController.prototype, "saveSettings", null);
510
+ __decorate([
511
+ Get('level1'),
512
+ __metadata("design:type", Function),
513
+ __metadata("design:paramtypes", []),
514
+ __metadata("design:returntype", Promise)
515
+ ], OperatorController.prototype, "level1", null);
516
+ __decorate([
517
+ Put('level1'),
518
+ __param(0, Body()),
519
+ __metadata("design:type", Function),
520
+ __metadata("design:paramtypes", [Object]),
521
+ __metadata("design:returntype", Promise)
522
+ ], OperatorController.prototype, "setLevel1", null);
523
+ __decorate([
524
+ Delete('level1'),
525
+ __metadata("design:type", Function),
526
+ __metadata("design:paramtypes", []),
527
+ __metadata("design:returntype", Promise)
528
+ ], OperatorController.prototype, "resetLevel1", null);
529
+ __decorate([
530
+ Get('presets'),
531
+ __metadata("design:type", Function),
532
+ __metadata("design:paramtypes", []),
533
+ __metadata("design:returntype", Promise)
534
+ ], OperatorController.prototype, "presets", null);
535
+ __decorate([
536
+ Put('presets/:name'),
537
+ __param(0, Param('name')),
538
+ __param(1, Body()),
539
+ __metadata("design:type", Function),
540
+ __metadata("design:paramtypes", [String, Object]),
541
+ __metadata("design:returntype", Promise)
542
+ ], OperatorController.prototype, "savePreset", null);
543
+ __decorate([
544
+ Delete('presets/:name'),
545
+ __param(0, Param('name')),
546
+ __metadata("design:type", Function),
547
+ __metadata("design:paramtypes", [String]),
548
+ __metadata("design:returntype", Promise)
549
+ ], OperatorController.prototype, "deletePreset", null);
550
+ __decorate([
551
+ Get('sessions'),
552
+ __metadata("design:type", Function),
553
+ __metadata("design:paramtypes", []),
554
+ __metadata("design:returntype", Promise)
555
+ ], OperatorController.prototype, "sessions", null);
556
+ __decorate([
557
+ Post('sessions'),
558
+ __param(0, Body()),
559
+ __metadata("design:type", Function),
560
+ __metadata("design:paramtypes", [Object]),
561
+ __metadata("design:returntype", Promise)
562
+ ], OperatorController.prototype, "createSession", null);
563
+ __decorate([
564
+ Get('sessions/:id'),
565
+ __param(0, Param('id')),
566
+ __metadata("design:type", Function),
567
+ __metadata("design:paramtypes", [String]),
568
+ __metadata("design:returntype", Promise)
569
+ ], OperatorController.prototype, "session", null);
570
+ __decorate([
571
+ Put('sessions/:id'),
572
+ __param(0, Param('id')),
573
+ __param(1, Body()),
574
+ __metadata("design:type", Function),
575
+ __metadata("design:paramtypes", [String, Object]),
576
+ __metadata("design:returntype", Promise)
577
+ ], OperatorController.prototype, "updateSession", null);
578
+ __decorate([
579
+ Delete('sessions/:id'),
580
+ __param(0, Param('id')),
581
+ __metadata("design:type", Function),
582
+ __metadata("design:paramtypes", [String]),
583
+ __metadata("design:returntype", Promise)
584
+ ], OperatorController.prototype, "deleteSession", null);
585
+ __decorate([
586
+ Post('sessions/:id/tasks'),
587
+ __param(0, Param('id')),
588
+ __param(1, Body()),
589
+ __metadata("design:type", Function),
590
+ __metadata("design:paramtypes", [String, Object]),
591
+ __metadata("design:returntype", Promise)
592
+ ], OperatorController.prototype, "addTask", null);
593
+ __decorate([
594
+ Put('sessions/:id/tasks/:taskId'),
595
+ __param(0, Param('id')),
596
+ __param(1, Param('taskId')),
597
+ __param(2, Body()),
598
+ __metadata("design:type", Function),
599
+ __metadata("design:paramtypes", [String, String, Object]),
600
+ __metadata("design:returntype", Promise)
601
+ ], OperatorController.prototype, "updateTask", null);
602
+ __decorate([
603
+ Delete('sessions/:id/tasks/:taskId'),
604
+ __param(0, Param('id')),
605
+ __param(1, Param('taskId')),
606
+ __metadata("design:type", Function),
607
+ __metadata("design:paramtypes", [String, String]),
608
+ __metadata("design:returntype", Promise)
609
+ ], OperatorController.prototype, "deleteTask", null);
610
+ __decorate([
611
+ Post('sessions/:id/tasks/:taskId/rerun'),
612
+ __param(0, Param('id')),
613
+ __param(1, Param('taskId')),
614
+ __param(2, Body()),
615
+ __metadata("design:type", Function),
616
+ __metadata("design:paramtypes", [String, String, Object]),
617
+ __metadata("design:returntype", Promise)
618
+ ], OperatorController.prototype, "rerunTask", null);
619
+ __decorate([
620
+ Get('sessions/:id/tasks/:taskId/restore'),
621
+ __param(0, Param('id')),
622
+ __param(1, Param('taskId')),
623
+ __metadata("design:type", Function),
624
+ __metadata("design:paramtypes", [String, String]),
625
+ __metadata("design:returntype", Promise)
626
+ ], OperatorController.prototype, "restorePreview", null);
627
+ __decorate([
628
+ Post('sessions/:id/tasks/:taskId/restore'),
629
+ __param(0, Param('id')),
630
+ __param(1, Param('taskId')),
631
+ __metadata("design:type", Function),
632
+ __metadata("design:paramtypes", [String, String]),
633
+ __metadata("design:returntype", Promise)
634
+ ], OperatorController.prototype, "restore", null);
635
+ __decorate([
636
+ Get('sessions/:id/tasks/:taskId/restart'),
637
+ __param(0, Param('id')),
638
+ __param(1, Param('taskId')),
639
+ __metadata("design:type", Function),
640
+ __metadata("design:paramtypes", [String, String]),
641
+ __metadata("design:returntype", Promise)
642
+ ], OperatorController.prototype, "restartPlan", null);
643
+ __decorate([
644
+ Post('sessions/:id/tasks/:taskId/restart'),
645
+ __param(0, Param('id')),
646
+ __param(1, Param('taskId')),
647
+ __param(2, Body()),
648
+ __metadata("design:type", Function),
649
+ __metadata("design:paramtypes", [String, String, Object]),
650
+ __metadata("design:returntype", Promise)
651
+ ], OperatorController.prototype, "restartFrom", null);
652
+ __decorate([
653
+ Get('sessions/:id/tasks/:taskId/log'),
654
+ __param(0, Param('id')),
655
+ __param(1, Param('taskId')),
656
+ __param(2, Res()),
657
+ __param(3, Query('run')),
658
+ __metadata("design:type", Function),
659
+ __metadata("design:paramtypes", [String, String, Object, String]),
660
+ __metadata("design:returntype", Promise)
661
+ ], OperatorController.prototype, "taskLog", null);
662
+ __decorate([
663
+ Post('sessions/:id/tasks/:taskId/log'),
664
+ __param(0, Param('id')),
665
+ __param(1, Param('taskId')),
666
+ __param(2, Query('run')),
667
+ __metadata("design:type", Function),
668
+ __metadata("design:paramtypes", [String, String, String]),
669
+ __metadata("design:returntype", Promise)
670
+ ], OperatorController.prototype, "saveTaskLog", null);
671
+ __decorate([
672
+ Get('sessions/:id/tasks/:taskId/story'),
673
+ __param(0, Param('id')),
674
+ __param(1, Param('taskId')),
675
+ __param(2, Query('run')),
676
+ __metadata("design:type", Function),
677
+ __metadata("design:paramtypes", [String, String, String]),
678
+ __metadata("design:returntype", Promise)
679
+ ], OperatorController.prototype, "taskStory", null);
680
+ __decorate([
681
+ Get('sessions/:id/tasks/:taskId/files'),
682
+ __param(0, Param('id')),
683
+ __param(1, Param('taskId')),
684
+ __param(2, Query('run')),
685
+ __metadata("design:type", Function),
686
+ __metadata("design:paramtypes", [String, String, String]),
687
+ __metadata("design:returntype", Promise)
688
+ ], OperatorController.prototype, "taskFiles", null);
689
+ __decorate([
690
+ Get('sessions/:id/tasks/:taskId/files/:kind/:name'),
691
+ __param(0, Param('id')),
692
+ __param(1, Param('taskId')),
693
+ __param(2, Param('kind')),
694
+ __param(3, Param('name')),
695
+ __param(4, Res()),
696
+ __param(5, Query('run')),
697
+ __metadata("design:type", Function),
698
+ __metadata("design:paramtypes", [String, String, String, String, Object, String]),
699
+ __metadata("design:returntype", Promise)
700
+ ], OperatorController.prototype, "taskFile", null);
701
+ __decorate([
702
+ Post('sessions/:id/tasks/:taskId/files/:kind/:name'),
703
+ __param(0, Param('id')),
704
+ __param(1, Param('taskId')),
705
+ __param(2, Param('kind')),
706
+ __param(3, Param('name')),
707
+ __param(4, Query('run')),
708
+ __metadata("design:type", Function),
709
+ __metadata("design:paramtypes", [String, String, String, String, String]),
710
+ __metadata("design:returntype", Promise)
711
+ ], OperatorController.prototype, "saveTaskFile", null);
712
+ __decorate([
713
+ Get('sessions/:id/export'),
714
+ __param(0, Param('id')),
715
+ __param(1, Res()),
716
+ __param(2, Query('tasks')),
717
+ __param(3, Query('variant')),
718
+ __metadata("design:type", Function),
719
+ __metadata("design:paramtypes", [String, Object, String, String]),
720
+ __metadata("design:returntype", Promise)
721
+ ], OperatorController.prototype, "exportTasks", null);
722
+ __decorate([
723
+ Get('debug/export'),
724
+ __param(0, Res()),
725
+ __param(1, Query('sessions')),
726
+ __metadata("design:type", Function),
727
+ __metadata("design:paramtypes", [Object, String]),
728
+ __metadata("design:returntype", Promise)
729
+ ], OperatorController.prototype, "debugExport", null);
730
+ __decorate([
731
+ Post('export/bundle'),
732
+ __param(0, Res()),
733
+ __param(1, Body()),
734
+ __metadata("design:type", Function),
735
+ __metadata("design:paramtypes", [Object, Object]),
736
+ __metadata("design:returntype", Promise)
737
+ ], OperatorController.prototype, "exportBundle", null);
738
+ __decorate([
739
+ Get('export/:kind'),
740
+ __param(0, Param('kind')),
741
+ __param(1, Res()),
742
+ __param(2, Query('run')),
743
+ __param(3, Query('session')),
744
+ __param(4, Query('task')),
745
+ __metadata("design:type", Function),
746
+ __metadata("design:paramtypes", [String, Object, String, String, String]),
747
+ __metadata("design:returntype", Promise)
748
+ ], OperatorController.prototype, "exportView", null);
749
+ __decorate([
750
+ Post('sessions/:id/start'),
751
+ __param(0, Param('id')),
752
+ __param(1, Body()),
753
+ __metadata("design:type", Function),
754
+ __metadata("design:paramtypes", [String, Object]),
755
+ __metadata("design:returntype", Promise)
756
+ ], OperatorController.prototype, "start", null);
757
+ __decorate([
758
+ Post('sessions/:id/stop'),
759
+ __param(0, Param('id')),
760
+ __metadata("design:type", Function),
761
+ __metadata("design:paramtypes", [String]),
762
+ __metadata("design:returntype", Promise)
763
+ ], OperatorController.prototype, "stop", null);
764
+ __decorate([
765
+ Get('batch'),
766
+ __metadata("design:type", Function),
767
+ __metadata("design:paramtypes", []),
768
+ __metadata("design:returntype", Object)
769
+ ], OperatorController.prototype, "batch", null);
770
+ __decorate([
771
+ Get('batch/name'),
772
+ __param(0, Query('sessions')),
773
+ __metadata("design:type", Function),
774
+ __metadata("design:paramtypes", [String]),
775
+ __metadata("design:returntype", Promise)
776
+ ], OperatorController.prototype, "suggestRunName", null);
777
+ __decorate([
778
+ Post('batch/start'),
779
+ __param(0, Body()),
780
+ __metadata("design:type", Function),
781
+ __metadata("design:paramtypes", [Object]),
782
+ __metadata("design:returntype", Promise)
783
+ ], OperatorController.prototype, "startBatch", null);
784
+ __decorate([
785
+ Post('batch/stop'),
786
+ __metadata("design:type", Function),
787
+ __metadata("design:paramtypes", []),
788
+ __metadata("design:returntype", Promise)
789
+ ], OperatorController.prototype, "stopBatch", null);
790
+ __decorate([
791
+ Post('batch/pause'),
792
+ __metadata("design:type", Function),
793
+ __metadata("design:paramtypes", []),
794
+ __metadata("design:returntype", Promise)
795
+ ], OperatorController.prototype, "pauseBatch", null);
796
+ __decorate([
797
+ Post('batch/resume'),
798
+ __metadata("design:type", Function),
799
+ __metadata("design:paramtypes", []),
800
+ __metadata("design:returntype", Promise)
801
+ ], OperatorController.prototype, "resumeBatch", null);
802
+ __decorate([
803
+ Get('plan/brief'),
804
+ __param(0, Query('lang')),
805
+ __metadata("design:type", Function),
806
+ __metadata("design:paramtypes", [String]),
807
+ __metadata("design:returntype", Promise)
808
+ ], OperatorController.prototype, "planBrief", null);
809
+ __decorate([
810
+ Get('context/:kind'),
811
+ __param(0, Param('kind')),
812
+ __param(1, Query('lang')),
813
+ __metadata("design:type", Function),
814
+ __metadata("design:paramtypes", [String, String]),
815
+ __metadata("design:returntype", Promise)
816
+ ], OperatorController.prototype, "context", null);
817
+ __decorate([
818
+ Put('context/:kind'),
819
+ __param(0, Param('kind')),
820
+ __param(1, Body()),
821
+ __metadata("design:type", Function),
822
+ __metadata("design:paramtypes", [String, Object]),
823
+ __metadata("design:returntype", Promise)
824
+ ], OperatorController.prototype, "setContext", null);
825
+ __decorate([
826
+ Delete('context/:kind'),
827
+ __param(0, Param('kind')),
828
+ __param(1, Query('lang')),
829
+ __metadata("design:type", Function),
830
+ __metadata("design:paramtypes", [String, String]),
831
+ __metadata("design:returntype", Promise)
832
+ ], OperatorController.prototype, "resetContext", null);
833
+ __decorate([
834
+ Post('plan/check'),
835
+ __param(0, Body()),
836
+ __metadata("design:type", Function),
837
+ __metadata("design:paramtypes", [Object]),
838
+ __metadata("design:returntype", Promise)
839
+ ], OperatorController.prototype, "checkPlan", null);
840
+ __decorate([
841
+ Post('plan/import'),
842
+ __param(0, Body()),
843
+ __metadata("design:type", Function),
844
+ __metadata("design:paramtypes", [Object]),
845
+ __metadata("design:returntype", Promise)
846
+ ], OperatorController.prototype, "importPlan", null);
847
+ __decorate([
848
+ Get('sessions/:id/events'),
849
+ __param(0, Param('id')),
850
+ __metadata("design:type", Function),
851
+ __metadata("design:paramtypes", [String]),
852
+ __metadata("design:returntype", Object)
853
+ ], OperatorController.prototype, "events", null);
854
+ __decorate([
855
+ Sse('sessions/:id/stream'),
856
+ __param(0, Param('id')),
857
+ __metadata("design:type", Function),
858
+ __metadata("design:paramtypes", [String]),
859
+ __metadata("design:returntype", Observable)
860
+ ], OperatorController.prototype, "stream", null);
861
+ __decorate([
862
+ Get('approvals'),
863
+ __param(0, Query('session')),
864
+ __metadata("design:type", Function),
865
+ __metadata("design:paramtypes", [String]),
866
+ __metadata("design:returntype", Object)
867
+ ], OperatorController.prototype, "approvals", null);
868
+ __decorate([
869
+ Post('approvals/:id'),
870
+ __param(0, Param('id')),
871
+ __param(1, Body()),
872
+ __metadata("design:type", Function),
873
+ __metadata("design:paramtypes", [String, Object]),
874
+ __metadata("design:returntype", Object)
875
+ ], OperatorController.prototype, "decide", null);
876
+ __decorate([
877
+ Post('sessions/:id/mode'),
878
+ __param(0, Param('id')),
879
+ __param(1, Body()),
880
+ __metadata("design:type", Function),
881
+ __metadata("design:paramtypes", [String, Object]),
882
+ __metadata("design:returntype", Object)
883
+ ], OperatorController.prototype, "setMode", null);
884
+ __decorate([
885
+ Get('activity'),
886
+ __metadata("design:type", Function),
887
+ __metadata("design:paramtypes", []),
888
+ __metadata("design:returntype", Object)
889
+ ], OperatorController.prototype, "activity", null);
890
+ __decorate([
891
+ Get('project'),
892
+ __metadata("design:type", Function),
893
+ __metadata("design:paramtypes", []),
894
+ __metadata("design:returntype", Promise)
895
+ ], OperatorController.prototype, "project", null);
896
+ __decorate([
897
+ Put('project'),
898
+ __param(0, Body()),
899
+ __metadata("design:type", Function),
900
+ __metadata("design:paramtypes", [Object]),
901
+ __metadata("design:returntype", Promise)
902
+ ], OperatorController.prototype, "setProject", null);
903
+ __decorate([
904
+ Get('repo'),
905
+ __param(0, Query('dir')),
906
+ __metadata("design:type", Function),
907
+ __metadata("design:paramtypes", [String]),
908
+ __metadata("design:returntype", Object)
909
+ ], OperatorController.prototype, "repo", null);
910
+ __decorate([
911
+ Get('sessions/:id/vcs'),
912
+ __param(0, Param('id')),
913
+ __metadata("design:type", Function),
914
+ __metadata("design:paramtypes", [String]),
915
+ __metadata("design:returntype", Promise)
916
+ ], OperatorController.prototype, "vcsStatus", null);
917
+ __decorate([
918
+ Get('models'),
919
+ __metadata("design:type", Function),
920
+ __metadata("design:paramtypes", []),
921
+ __metadata("design:returntype", Promise)
922
+ ], OperatorController.prototype, "models", null);
923
+ __decorate([
924
+ Post('models/refresh'),
925
+ __metadata("design:type", Function),
926
+ __metadata("design:paramtypes", []),
927
+ __metadata("design:returntype", Promise)
928
+ ], OperatorController.prototype, "refreshModels", null);
929
+ __decorate([
930
+ Put('models/default'),
931
+ __param(0, Body()),
932
+ __metadata("design:type", Function),
933
+ __metadata("design:paramtypes", [Object]),
934
+ __metadata("design:returntype", Promise)
935
+ ], OperatorController.prototype, "setDefaultModel", null);
936
+ __decorate([
937
+ Put('models/review-default'),
938
+ __param(0, Body()),
939
+ __metadata("design:type", Function),
940
+ __metadata("design:paramtypes", [Object]),
941
+ __metadata("design:returntype", Promise)
942
+ ], OperatorController.prototype, "setDefaultReviewModel", null);
943
+ __decorate([
944
+ Get('tasks'),
945
+ __metadata("design:type", Function),
946
+ __metadata("design:paramtypes", []),
947
+ __metadata("design:returntype", Promise)
948
+ ], OperatorController.prototype, "tasks", null);
949
+ __decorate([
950
+ Get('dirs'),
951
+ __param(0, Query('root')),
952
+ __param(1, Query('gitignore')),
953
+ __metadata("design:type", Function),
954
+ __metadata("design:paramtypes", [String, String]),
955
+ __metadata("design:returntype", Promise)
956
+ ], OperatorController.prototype, "dirs", null);
957
+ __decorate([
958
+ Post('browse-folder'),
959
+ __param(0, Body()),
960
+ __metadata("design:type", Function),
961
+ __metadata("design:paramtypes", [Object]),
962
+ __metadata("design:returntype", Promise)
963
+ ], OperatorController.prototype, "browseFolder", null);
964
+ __decorate([
965
+ Post('mirror/preview'),
966
+ __param(0, Body()),
967
+ __metadata("design:type", Function),
968
+ __metadata("design:paramtypes", [Object]),
969
+ __metadata("design:returntype", Promise)
970
+ ], OperatorController.prototype, "preview", null);
971
+ OperatorController = __decorate([
972
+ Controller(),
973
+ __metadata("design:paramtypes", [OperatorService])
974
+ ], OperatorController);
975
+ export { OperatorController };