copilot-operator 0.1.22 → 0.1.23

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 (34) hide show
  1. package/dist/src/api/operator.controller.js +1 -1
  2. package/dist/src/api/operator.service.js +4 -2
  3. package/dist/src/plan/systemGuide.js +24 -0
  4. package/dist/src/vcs/git.js +4 -2
  5. package/dist/src/vcs/prepareFromRemote.js +38 -8
  6. package/dist/src/vcs/remoteAuth.js +61 -0
  7. package/dist/web/404.html +2 -2
  8. package/dist/web/_next/static/chunks/549-df7a4876917615da.js +1 -0
  9. package/dist/web/_next/static/chunks/867-a67ea8ba3f9b24aa.js +1 -0
  10. package/dist/web/_next/static/chunks/app/defaults/{page-cdc730adea753446.js → page-0e778dafc69afbd3.js} +1 -1
  11. package/dist/web/_next/static/chunks/app/sessions/view/{page-185755ada66e2930.js → page-9b66b729748595bb.js} +1 -1
  12. package/dist/web/appearance.html +2 -2
  13. package/dist/web/appearance.txt +10 -10
  14. package/dist/web/defaults.html +2 -2
  15. package/dist/web/defaults.txt +10 -10
  16. package/dist/web/history.html +2 -2
  17. package/dist/web/history.txt +10 -10
  18. package/dist/web/import.html +2 -2
  19. package/dist/web/import.txt +10 -10
  20. package/dist/web/index.html +2 -2
  21. package/dist/web/index.txt +10 -10
  22. package/dist/web/level1.html +2 -2
  23. package/dist/web/level1.txt +10 -10
  24. package/dist/web/presets.html +2 -2
  25. package/dist/web/presets.txt +10 -10
  26. package/dist/web/sessions/view.html +2 -2
  27. package/dist/web/sessions/view.txt +10 -10
  28. package/dist/web/system.html +2 -2
  29. package/dist/web/system.txt +10 -10
  30. package/package.json +1 -1
  31. package/dist/web/_next/static/chunks/549-5f90780046c1c24f.js +0 -1
  32. package/dist/web/_next/static/chunks/867-79f07bebe3084811.js +0 -1
  33. /package/dist/web/_next/static/{9Ze8aagkvT-WLfD4KCKKS → -dZtu-yqxc-HXzYTmqYSc}/_buildManifest.js +0 -0
  34. /package/dist/web/_next/static/{9Ze8aagkvT-WLfD4KCKKS → -dZtu-yqxc-HXzYTmqYSc}/_ssgManifest.js +0 -0
@@ -498,7 +498,7 @@ let OperatorController = class OperatorController {
498
498
  }
499
499
  /** "Prepare the folder from the remote main branch": what it would do (fetches, changes nothing else). */
500
500
  repoPreparePreview(body) {
501
- return this.ops.preparePreview(body?.dir ?? '').catch(fail);
501
+ return this.ops.preparePreview(body?.dir ?? '', body?.fetch !== false).catch(fail);
502
502
  }
503
503
  /** …and doing it, if the folder is still what the preview showed. */
504
504
  repoPrepare(body) {
@@ -46,6 +46,7 @@ import { createTransport } from '../transport/chatTransport.js';
46
46
  import { composeHandoff } from '../session/handoff.js';
47
47
  import { planSync } from '../vcs/syncCommand.js';
48
48
  import { planPrepare, prepareFromRemote } from '../vcs/prepareFromRemote.js';
49
+ import { askpassProgram } from '../vcs/remoteAuth.js';
49
50
  import { appendRunLog } from '../session/runLog.js';
50
51
  import { dirtyPolicy, takeSnapshot } from '../vcs/snapshot.js';
51
52
  import { runVcsPreflight, runVcsPrepare } from '../vcs/runPreflight.js';
@@ -2489,10 +2490,11 @@ let OperatorService = class OperatorService {
2489
2490
  * "Prepare the folder from the remote main branch", first half: fetches and says what would be
2490
2491
  * kept where and what the folder would be. See `vcs/prepareFromRemote.ts`.
2491
2492
  */
2492
- async preparePreview(dir) {
2493
+ async preparePreview(dir, fetch = true) {
2493
2494
  await this.init();
2494
2495
  await this.knownProjectFolder(dir, 'it is not prepared from here');
2495
- return await planPrepare(resolve(dir.trim()), { fetch: true });
2496
+ // The operator pressed the button and is looking: the remote may ask for a password through Git's own window.
2497
+ return await planPrepare(resolve(dir.trim()), { fetch, askpass: fetch ? await askpassProgram() : null });
2496
2498
  }
2497
2499
  /**
2498
2500
  * The second half: does it, if the folder is still what the preview showed. Refused while anything
@@ -2956,6 +2956,30 @@ export const SYSTEM_GUIDE = [
2956
2956
  doesEn: 'Keeps everything as shown, then checks out the remote main branch as the local one and removes the new files from the folder (they are on the saved branch); ignored files stay. Refused if the folder changed since the preview, or while a run works in it. Afterwards the operator adds the files a task needs and the run screen offers a starting snapshot of them.',
2957
2957
  doesBg: 'Запазва всичко, както е показано, после избира основния клон на remote като локален и маха новите файлове от папката (те са в запазения клон); игнорираните остават. Отказва се, ако папката се е променила след прегледа или докато пускане работи в нея. След това операторът добавя файловете за задачата и екранът за пускане предлага начална снимка от тях.',
2958
2958
  },
2959
+ {
2960
+ key: 'prep.retry',
2961
+ kind: 'button',
2962
+ en: 'Try again',
2963
+ bg: 'Опитай пак',
2964
+ doesEn: 'Shown when the fetch did not get through: fetches again; a remote that wants a password or an SSH key passphrase asks through Git\u2019s own window, which the bot never reads.',
2965
+ doesBg: 'Показва се, когато изтеглянето не е минало: изтегля отново; remote, който иска парола или passphrase за SSH ключ, пита през собствения прозорец на Git, който ботът не чете.',
2966
+ },
2967
+ {
2968
+ key: 'prep.copyFetch',
2969
+ kind: 'button',
2970
+ en: 'Copy the fetch command',
2971
+ bg: 'Копирай командата за изтегляне',
2972
+ doesEn: 'Copies git fetch for this repository, to run in the operator\u2019s own PowerShell, where ssh asks for the passphrase directly.',
2973
+ doesBg: 'Копира git fetch за това хранилище, за собствения PowerShell на оператора, където ssh пита за passphrase директно.',
2974
+ },
2975
+ {
2976
+ key: 'prep.useFetched',
2977
+ kind: 'button',
2978
+ en: 'Continue with what was last fetched',
2979
+ bg: 'Продължи с последно изтегленото',
2980
+ doesEn: 'The preview again without fetching, against the remote as it was last fetched (say, by the command above); it says when that was.',
2981
+ doesBg: 'Прегледът отново без изтегляне, спрямо remote, както е изтеглен последно (например с командата по-горе); казва кога е било.',
2982
+ },
2959
2983
  {
2960
2984
  key: 'prep.cancel',
2961
2985
  kind: 'button',
@@ -44,9 +44,11 @@ function noHooksDir() {
44
44
  return process.env.SystemRoot ? join(process.env.SystemRoot, 'System32', 'copilot-operator-no-hooks') : '/nonexistent';
45
45
  }
46
46
  /** Runs one git command in a directory. Never throws: the caller decides what a failure means. */
47
- export function git(cwd, args, timeoutMs = 60_000, env) {
47
+ export function git(cwd, args, timeoutMs = 60_000, env,
48
+ /** `windowsHide: false` only for a fetch the operator is sitting at, whose password window must be seen. */
49
+ opts = {}) {
48
50
  return new Promise((resolve) => {
49
- execFile('git', [...SAFE_GIT, ...args], { cwd, timeout: timeoutMs, windowsHide: true, maxBuffer: 8 * 1024 * 1024, ...(env ? { env } : {}) }, (error, stdout, stderr) => {
51
+ execFile('git', [...SAFE_GIT, ...args], { cwd, timeout: timeoutMs, windowsHide: opts.windowsHide ?? true, maxBuffer: 8 * 1024 * 1024, ...(env ? { env } : {}) }, (error, stdout, stderr) => {
50
52
  const code = error?.code;
51
53
  resolve({
52
54
  ok: !error,
@@ -24,13 +24,13 @@
24
24
  * The preview fetches (so what it shows is against the remote as it is now) and changes nothing else;
25
25
  * the preparation itself refuses when the folder is no longer what the preview showed.
26
26
  */
27
- import { existsSync } from 'node:fs';
27
+ import { existsSync, statSync } from 'node:fs';
28
28
  import { rm } from 'node:fs/promises';
29
29
  import { tmpdir } from 'node:os';
30
30
  import { join, resolve } from 'node:path';
31
31
  import { createHash } from 'node:crypto';
32
32
  import { branchNameFrom, freeBranchName, git, porcelainPaths, RUNNER_EMAIL } from './git.js';
33
- const QUIET = { ...process.env, GIT_TERMINAL_PROMPT: '0', GCM_INTERACTIVE: 'never', GIT_ASKPASS: '', SSH_ASKPASS: '' };
33
+ import { describeFetchFailure, fetchCommandFor, operatorFetchEnv, QUIET_FETCH_ENV } from './remoteAuth.js';
34
34
  const short = (c) => (c ?? '').slice(0, 8);
35
35
  const lines = (s) => s.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
36
36
  function stamp(now = new Date()) {
@@ -62,7 +62,9 @@ const empty = (repoDir, problem) => ({
62
62
  });
63
63
  /**
64
64
  * What preparing the folder would do. Fetches the remote when `fetch` is true (the preview); reads
65
- * only when it is false (the preparation, which must compare against what the preview fetched).
65
+ * only when it is false (the preparation, which must compare against what the preview fetched, or a
66
+ * preview after the operator fetched in their own terminal). With `askpass`, the fetch may ask for a
67
+ * password through that program (see `remoteAuth.ts`); without it, it may not ask at all.
66
68
  */
67
69
  export async function planPrepare(folder, opts) {
68
70
  const inside = await git(folder, ['rev-parse', '--is-inside-work-tree']);
@@ -84,13 +86,32 @@ export async function planPrepare(folder, opts) {
84
86
  if (remotes.length === 0)
85
87
  return empty(repoDir, 'The repository has no remote, so there is no remote main branch to prepare it from.');
86
88
  const remote = remotes.includes('origin') ? 'origin' : remotes[0];
89
+ const lastFetchedAt = () => {
90
+ try {
91
+ return gitDir ? statSync(join(gitDir, 'FETCH_HEAD')).mtime.toISOString() : undefined;
92
+ }
93
+ catch {
94
+ return undefined;
95
+ }
96
+ };
97
+ const fetchCommand = fetchCommandFor(repoDir, remote);
87
98
  let fetched;
88
99
  if (opts.fetch) {
89
- const f = await git(repoDir, ['-c', 'credential.interactive=false', 'fetch', '--quiet', '--no-tags', '--prune', remote], 120_000, QUIET);
90
- fetched = f.ok ? { ok: true } : { ok: false, detail: (f.stderr || f.stdout || 'git fetch failed').split(/\r?\n/)[0] };
91
- // The remote's own idea of its main branch, asked of it now; a remote that will not say keeps the old answer.
100
+ /*
101
+ * With the password window: five minutes for the operator to type, and the window not hidden. One
102
+ * connection only — `remote set-head --auto` would open a second and ask for the password again —
103
+ * so the remote's main is read from what was fetched, below.
104
+ */
105
+ const asked = !!opts.askpass;
106
+ const env = asked ? operatorFetchEnv(opts.askpass) : QUIET_FETCH_ENV;
107
+ const args = [...(asked ? [] : ['-c', 'credential.interactive=false']), 'fetch', '--quiet', '--no-tags', '--prune', remote];
108
+ const f = await git(repoDir, args, asked ? 300_000 : 120_000, env, { windowsHide: !asked });
92
109
  if (f.ok)
93
- await git(repoDir, ['remote', 'set-head', remote, '--auto'], 60_000, QUIET);
110
+ fetched = { ok: true, asked };
111
+ else {
112
+ const why = describeFetchFailure(f.stderr || f.stdout);
113
+ fetched = { ok: false, detail: why.detail, auth: why.auth, asked };
114
+ }
94
115
  }
95
116
  let target = '';
96
117
  const remoteHead = await git(repoDir, ['symbolic-ref', '--quiet', '--short', `refs/remotes/${remote}/HEAD`]);
@@ -102,14 +123,21 @@ export async function planPrepare(folder, opts) {
102
123
  if ((await git(repoDir, ['rev-parse', '--verify', '--quiet', `refs/remotes/${remote}/${name}`])).ok)
103
124
  target = `${remote}/${name}`;
104
125
  }
126
+ const last = lastFetchedAt();
105
127
  if (!target) {
106
128
  return {
107
129
  ...empty(repoDir, fetched && !fetched.ok ? `The remote could not be fetched (${fetched.detail}), and no main branch of ${remote} is known here.` : `No main branch of ${remote} is known here.`),
108
130
  ...(fetched ? { fetched } : {}),
131
+ fetchCommand,
109
132
  };
110
133
  }
111
134
  if (fetched && !fetched.ok) {
112
- return { ...empty(repoDir, `The remote could not be fetched, so the folder would be set to an old copy of ${target}: ${fetched.detail}. Nothing was changed.`), fetched };
135
+ return {
136
+ ...empty(repoDir, `The remote could not be fetched, so the folder would be set to an old copy of ${target}: ${fetched.detail}. Nothing was changed.`),
137
+ fetched,
138
+ fetchCommand,
139
+ ...(last ? { lastFetched: last } : {}),
140
+ };
113
141
  }
114
142
  const targetCommit = (await git(repoDir, ['rev-parse', '--verify', '--quiet', `refs/remotes/${target}^{commit}`])).stdout;
115
143
  if (!targetCommit)
@@ -144,6 +172,8 @@ export async function planPrepare(folder, opts) {
144
172
  localBranch,
145
173
  localHead,
146
174
  ...(fetched ? { fetched } : {}),
175
+ ...(last ? { lastFetched: last } : {}),
176
+ fetchCommand,
147
177
  changed,
148
178
  untracked,
149
179
  mainOnlyCommits,
@@ -0,0 +1,61 @@
1
+ /**
2
+ * How a fetch the operator asked for gets past a remote that wants a password — without the bot ever
3
+ * seeing it.
4
+ *
5
+ * Found on 2026-10-03 with "Prepare the folder from the remote main branch": the remote is reached over
6
+ * SSH with a key that has a passphrase, and every fetch the bot makes forbids prompts (a prompt in a
7
+ * run nobody watches would hang it), so the fetch failed. The operator asked for a safe way to type the
8
+ * passphrase.
9
+ *
10
+ * Not a field on the bot's page: a password typed there passes through the browser, the API, this
11
+ * process and its memory, and the bot would hold the one secret that unlocks the operator's key. So
12
+ * the bot asks nobody anything. It lets ssh (and git, for HTTPS) ask through Git for Windows' own
13
+ * password window, `git-askpass.exe`: ssh starts the window, the operator types into it, and the
14
+ * answer goes from the window straight back to ssh through a pipe the bot is not part of. Nothing is
15
+ * stored; the next fetch asks again (an ssh-agent, if the operator runs one, answers instead).
16
+ *
17
+ * Only for a fetch the operator just pressed a button for: a run's own fetches stay silent, since a
18
+ * window nobody answers would hold the run until it times out.
19
+ */
20
+ import { existsSync } from 'node:fs';
21
+ import { resolve } from 'node:path';
22
+ import { git } from './git.js';
23
+ import { psQuote } from './syncCommand.js';
24
+ /** No prompt anywhere: what every fetch of a run uses. */
25
+ export const QUIET_FETCH_ENV = { ...process.env, GIT_TERMINAL_PROMPT: '0', GCM_INTERACTIVE: 'never', GIT_ASKPASS: '', SSH_ASKPASS: '' };
26
+ /** Git for Windows' password window, next to the git that runs here; null when there is none. */
27
+ export async function askpassProgram() {
28
+ const exec = await git(process.cwd(), ['--exec-path']);
29
+ if (!exec.ok || !exec.stdout)
30
+ return null;
31
+ // <Git>\mingw64\libexec\git-core → <Git>\mingw64\bin\git-askpass.exe
32
+ const candidate = resolve(exec.stdout, '..', '..', 'bin', 'git-askpass.exe');
33
+ return existsSync(candidate) ? candidate : null;
34
+ }
35
+ /**
36
+ * The environment for a fetch the operator is present for: ssh asks through the password window even
37
+ * with no terminal (`SSH_ASKPASS_REQUIRE=force`; `DISPLAY` for an older ssh that wants one), and git
38
+ * asks through it for an HTTPS user name or password that its credential manager does not answer. No
39
+ * terminal prompt: the bot's console is not where the operator is looking.
40
+ */
41
+ export function operatorFetchEnv(askpass) {
42
+ return {
43
+ ...process.env,
44
+ GIT_TERMINAL_PROMPT: '0',
45
+ GCM_INTERACTIVE: 'auto',
46
+ GIT_ASKPASS: askpass,
47
+ SSH_ASKPASS: askpass,
48
+ SSH_ASKPASS_REQUIRE: 'force',
49
+ DISPLAY: process.env.DISPLAY || 'needs-to-be-defined',
50
+ };
51
+ }
52
+ /** A failed fetch, said so the operator knows whether it was the password. */
53
+ export function describeFetchFailure(stderr) {
54
+ const lines = stderr.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
55
+ const auth = /permission denied|publickey|passphrase|authentication failed|could not read (username|password)|host key verification failed|terminal prompts disabled/i.test(stderr);
56
+ return { detail: lines.slice(0, 3).join(' ') || 'git fetch failed', auth };
57
+ }
58
+ /** The fetch for the operator to run in their own PowerShell, where ssh can ask them directly. */
59
+ export function fetchCommandFor(dir, remote) {
60
+ return `git -C ${psQuote(dir)} fetch --prune ${psQuote(remote)}`;
61
+ }
package/dist/web/404.html CHANGED
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><!--9Ze8aagkvT_WLfD4KCKKS--><html lang="en" data-theme="light" data-textsize="normal" data-contrast="normal" data-motion="normal" data-links="plain" data-focus="normal"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/c37978b44194c37b.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0f31b926d9a9c5a4.js"/><script src="/_next/static/chunks/c7879cf7-b5ab1053c1d9a2e7.js" async=""></script><script src="/_next/static/chunks/131-bae98f790a541679.js" async=""></script><script src="/_next/static/chunks/main-app-e3a5f713ba31557e.js" async=""></script><script src="/_next/static/chunks/197-f7c33a0114fc3db3.js" async=""></script><script src="/_next/static/chunks/867-79f07bebe3084811.js" async=""></script><script src="/_next/static/chunks/549-5f90780046c1c24f.js" async=""></script><script src="/_next/static/chunks/app/layout-3efbb282292ccc38.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>copilot-operator</title><meta name="description" content="Runs task loops with Microsoft 365 Copilot on this machine."/><script>
1
+ <!DOCTYPE html><!--_dZtu_yqxc_HXzYTmqYSc--><html lang="en" data-theme="light" data-textsize="normal" data-contrast="normal" data-motion="normal" data-links="plain" data-focus="normal"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/c37978b44194c37b.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0f31b926d9a9c5a4.js"/><script src="/_next/static/chunks/c7879cf7-b5ab1053c1d9a2e7.js" async=""></script><script src="/_next/static/chunks/131-bae98f790a541679.js" async=""></script><script src="/_next/static/chunks/main-app-e3a5f713ba31557e.js" async=""></script><script src="/_next/static/chunks/197-f7c33a0114fc3db3.js" async=""></script><script src="/_next/static/chunks/867-a67ea8ba3f9b24aa.js" async=""></script><script src="/_next/static/chunks/549-df7a4876917615da.js" async=""></script><script src="/_next/static/chunks/app/layout-3efbb282292ccc38.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>copilot-operator</title><meta name="description" content="Runs task loops with Microsoft 365 Copilot on this machine."/><script>
2
2
  (function () {
3
3
  try {
4
4
  var d = document.documentElement;
@@ -13,4 +13,4 @@
13
13
  d.dataset.focus = a.strongFocus ? 'strong' : 'normal';
14
14
  } catch (e) {}
15
15
  })();
16
- </script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><a class="skip-link" href="#main">Skip to the content</a><div class="wrap"><header class="top"><h1><a href="/">copilot-operator</a></h1><nav aria-label="Main"><a href="/"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M4 5h16v4H4zM4 11h16v4H4zM4 17h10v2H4z"></path></svg><span>Sessions</span></a><a href="/defaults"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm8.5 4 1.5 1-1.6 2.8-1.8-.4a7 7 0 0 1-1.5 1.5l.4 1.8L14.7 21l-1-1.5a7 7 0 0 1-3.4 0l-1 1.5-2.8-1.6.4-1.8A7 7 0 0 1 5.4 16l-1.8.4L2 13.6 3.5 12.6V11.4L2 10.4l1.6-2.8 1.8.4A7 7 0 0 1 6.9 6.5l-.4-1.8L9.3 3l1 1.5a7 7 0 0 1 3.4 0l1-1.5 2.8 1.6-.4 1.8a7 7 0 0 1 1.5 1.5l1.8-.4L22 10.4l-1.5 1z"></path></svg><span>Settings</span></a><a href="/import"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3v10m0 0 4-4m-4 4-4-4M4 15v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Plan from JSON</span></a><a href="/history"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3a9 9 0 1 0 8.5 6M12 7v5l3 2M3 4v5h5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Task register</span></a><a href="/level1"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M6 3h9l5 5v13H6zM14 3v6h6M9 13h7M9 17h7" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>Level 1 prompt</span></a><a href="/presets"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M5 4h14v4H5zM5 10h14v4H5zM5 16h9v4H5z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>Level 2 presets</span></a><a href="/appearance"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3a9 9 0 0 0 0 18c1.5 0 2-1 2-2s-1-1.5-1-2.5S14 15 15.5 15H17a4 4 0 0 0 4-4 8 8 0 0 0-9-8zM8 9a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm4-3a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm4 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"></path></svg><span>Appearance</span></a><a href="/system"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M4 5h16v10H4zM2 19h20M9 15v4M15 15v4" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>System</span></a><select aria-label="Language" style="width:auto"><option value="en" selected="">English</option><option value="bg">Български</option></select></nav></header><main id="main"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--></main></div><script src="/_next/static/chunks/webpack-0f31b926d9a9c5a4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[8078,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"AppearanceProvider\"]\n3:I[867,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"LanguageProvider\"]\n4:I[1035,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"DialogHost\"]\n5:I[8214,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"SkipLink\"]\n6:I[8197,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"\"]\n7:I[8214,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"Nav\"]\n8:I[6657,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"GlobalApprovals\"]\n9:I[5204,[],\"\"]\na:I[2642,[],\"\"]\nb:I[7712,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-79f07bebe3084811.js\",\"549\",\"static/chunks/549-5f90780046c1c24f.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"ScrollJump\"]\nc:I[433,[],\"OutletBoundary\"]\ne:I[9884,[],\"AsyncMetadataOutlet\"]\n10:I[433,[],\"ViewportBoundary\"]\n12:I[433,[],\"MetadataBoundary\"]\n13:\"$Sreact.suspense\"\n15:I[3536,[],\"\"]\n:HL[\"/_next/static/css/c37978b44194c37b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"9Ze8aagkvT-WLfD4KCKKS\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c37978b44194c37b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"data-theme\":\"light\",\"data-textsize\":\"normal\",\"data-contrast\":\"normal\",\"data-motion\":\"normal\",\"data-links\":\"plain\",\"data-focus\":\"normal\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n(function () {\\n try {\\n var d = document.documentElement;\\n var raw = localStorage.getItem('cop.appearance');\\n var a = raw ? JSON.parse(raw) : {};\\n if (!a || typeof a !== 'object') a = {};\\n d.dataset.theme = a.theme === 'dark' ? 'dark' : 'light';\\n d.dataset.textsize = [\\\"small\\\",\\\"normal\\\",\\\"large\\\",\\\"huge\\\",\\\"giant\\\"].indexOf(a.textSize) \u003e= 0 ? a.textSize : 'normal';\\n d.dataset.contrast = a.highContrast ? 'high' : 'normal';\\n d.dataset.motion = a.reduceMotion ? 'reduced' : 'normal';\\n d.dataset.links = a.underlineLinks ? 'underline' : 'plain';\\n d.dataset.focus = a.strongFocus ? 'strong' : 'normal';\\n } catch (e) {}\\n})();\\n\"}}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"div\",null,{\"className\":\"wrap\",\"children\":[[\"$\",\"header\",null,{\"className\":\"top\",\"children\":[[\"$\",\"h1\",null,{\"children\":[\"$\",\"$L6\",null,{\"href\":\"/\",\"children\":\"copilot-operator\"}]}],[\"$\",\"$L7\",null,{}]]}],[\"$\",\"$L8\",null,{}],[\"$\",\"main\",null,{\"id\":\"main\",\"children\":[\"$\",\"$L9\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}],[\"$\",\"$Lb\",null,{}]]}]}]}]}]]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L9\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$Lc\",null,{\"children\":[\"$Ld\",[\"$\",\"$Le\",null,{\"promise\":\"$@f\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L10\",null,{\"children\":\"$L11\"}],null],[\"$\",\"$L12\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$13\",null,{\"fallback\":null,\"children\":\"$L14\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$15\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"11:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\nd:null\n"])</script><script>self.__next_f.push([1,"f:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"copilot-operator\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Runs task loops with Microsoft 365 Copilot on this machine.\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"14:\"$f:metadata\"\n"])</script></body></html>
16
+ </script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><a class="skip-link" href="#main">Skip to the content</a><div class="wrap"><header class="top"><h1><a href="/">copilot-operator</a></h1><nav aria-label="Main"><a href="/"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M4 5h16v4H4zM4 11h16v4H4zM4 17h10v2H4z"></path></svg><span>Sessions</span></a><a href="/defaults"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm8.5 4 1.5 1-1.6 2.8-1.8-.4a7 7 0 0 1-1.5 1.5l.4 1.8L14.7 21l-1-1.5a7 7 0 0 1-3.4 0l-1 1.5-2.8-1.6.4-1.8A7 7 0 0 1 5.4 16l-1.8.4L2 13.6 3.5 12.6V11.4L2 10.4l1.6-2.8 1.8.4A7 7 0 0 1 6.9 6.5l-.4-1.8L9.3 3l1 1.5a7 7 0 0 1 3.4 0l1-1.5 2.8 1.6-.4 1.8a7 7 0 0 1 1.5 1.5l1.8-.4L22 10.4l-1.5 1z"></path></svg><span>Settings</span></a><a href="/import"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3v10m0 0 4-4m-4 4-4-4M4 15v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Plan from JSON</span></a><a href="/history"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3a9 9 0 1 0 8.5 6M12 7v5l3 2M3 4v5h5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Task register</span></a><a href="/level1"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M6 3h9l5 5v13H6zM14 3v6h6M9 13h7M9 17h7" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>Level 1 prompt</span></a><a href="/presets"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M5 4h14v4H5zM5 10h14v4H5zM5 16h9v4H5z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>Level 2 presets</span></a><a href="/appearance"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M12 3a9 9 0 0 0 0 18c1.5 0 2-1 2-2s-1-1.5-1-2.5S14 15 15.5 15H17a4 4 0 0 0 4-4 8 8 0 0 0-9-8zM8 9a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm4-3a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm4 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"></path></svg><span>Appearance</span></a><a href="/system"><svg class="nav-icon" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M4 5h16v10H4zM2 19h20M9 15v4M15 15v4" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path></svg><span>System</span></a><select aria-label="Language" style="width:auto"><option value="en" selected="">English</option><option value="bg">Български</option></select></nav></header><main id="main"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--></main></div><script src="/_next/static/chunks/webpack-0f31b926d9a9c5a4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[8078,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"AppearanceProvider\"]\n3:I[867,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"LanguageProvider\"]\n4:I[1035,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"DialogHost\"]\n5:I[8214,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"SkipLink\"]\n6:I[8197,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"\"]\n7:I[8214,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"Nav\"]\n8:I[6657,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"GlobalApprovals\"]\n9:I[5204,[],\"\"]\na:I[2642,[],\"\"]\nb:I[7712,[\"197\",\"static/chunks/197-f7c33a0114fc3db3.js\",\"867\",\"static/chunks/867-a67ea8ba3f9b24aa.js\",\"549\",\"static/chunks/549-df7a4876917615da.js\",\"177\",\"static/chunks/app/layout-3efbb282292ccc38.js\"],\"ScrollJump\"]\nc:I[433,[],\"OutletBoundary\"]\ne:I[9884,[],\"AsyncMetadataOutlet\"]\n10:I[433,[],\"ViewportBoundary\"]\n12:I[433,[],\"MetadataBoundary\"]\n13:\"$Sreact.suspense\"\n15:I[3536,[],\"\"]\n:HL[\"/_next/static/css/c37978b44194c37b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"-dZtu-yqxc-HXzYTmqYSc\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c37978b44194c37b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"data-theme\":\"light\",\"data-textsize\":\"normal\",\"data-contrast\":\"normal\",\"data-motion\":\"normal\",\"data-links\":\"plain\",\"data-focus\":\"normal\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n(function () {\\n try {\\n var d = document.documentElement;\\n var raw = localStorage.getItem('cop.appearance');\\n var a = raw ? JSON.parse(raw) : {};\\n if (!a || typeof a !== 'object') a = {};\\n d.dataset.theme = a.theme === 'dark' ? 'dark' : 'light';\\n d.dataset.textsize = [\\\"small\\\",\\\"normal\\\",\\\"large\\\",\\\"huge\\\",\\\"giant\\\"].indexOf(a.textSize) \u003e= 0 ? a.textSize : 'normal';\\n d.dataset.contrast = a.highContrast ? 'high' : 'normal';\\n d.dataset.motion = a.reduceMotion ? 'reduced' : 'normal';\\n d.dataset.links = a.underlineLinks ? 'underline' : 'plain';\\n d.dataset.focus = a.strongFocus ? 'strong' : 'normal';\\n } catch (e) {}\\n})();\\n\"}}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"div\",null,{\"className\":\"wrap\",\"children\":[[\"$\",\"header\",null,{\"className\":\"top\",\"children\":[[\"$\",\"h1\",null,{\"children\":[\"$\",\"$L6\",null,{\"href\":\"/\",\"children\":\"copilot-operator\"}]}],[\"$\",\"$L7\",null,{}]]}],[\"$\",\"$L8\",null,{}],[\"$\",\"main\",null,{\"id\":\"main\",\"children\":[\"$\",\"$L9\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}],[\"$\",\"$Lb\",null,{}]]}]}]}]}]]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L9\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$Lc\",null,{\"children\":[\"$Ld\",[\"$\",\"$Le\",null,{\"promise\":\"$@f\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L10\",null,{\"children\":\"$L11\"}],null],[\"$\",\"$L12\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$13\",null,{\"fallback\":null,\"children\":\"$L14\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$15\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"11:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\nd:null\n"])</script><script>self.__next_f.push([1,"f:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"copilot-operator\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Runs task loops with Microsoft 365 Copilot on this machine.\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"14:\"$f:metadata\"\n"])</script></body></html>
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[549],{5549:(t,e,o)=>{o.d(e,{AV:()=>a,FH:()=>h,FZ:()=>r,Zm:()=>u,aT:()=>s,c5:()=>y,dK:()=>l,nC:()=>n,rt:()=>d,ub:()=>i,zi:()=>p});let n="/api";function s(t,e){return"/sessions/view?id=".concat(encodeURIComponent(t)).concat(e?"#".concat(e):"")}let c="cop-api-token";function a(){try{let t=/(?:^#|&)token=([0-9a-f]{16,})/i.exec(window.location.hash);if(t)return window.localStorage.setItem(c,t[1]),window.history.replaceState(null,"",window.location.pathname+window.location.search),t[1];return window.localStorage.getItem(c)||""}catch(t){return""}}function i(t){let e=a();return e?"".concat(t).concat(t.includes("?")?"&":"?","token=").concat(encodeURIComponent(e)):t}let r=["exit-zero","exit-nonzero","output-contains","output-omits","output-matches","file-exists","file-missing","file-contains"];function d(t){return t.startsWith("exit-")||t.startsWith("output-")}function l(t){return"output-contains"===t||"output-omits"===t||"output-matches"===t||"file-contains"===t}function u(t){return"limit-reached"===t.status||"aborted"===t.status||!!t.limit&&("failed"===t.status||"blocked"===t.status)}async function m(t,e){let o,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},c=void 0===s.timeoutMs?3e4:s.timeoutMs;try{var i;o=await fetch("".concat(n).concat(t),{...e,...null!==c&&!(null==e?void 0:e.signal)?{signal:AbortSignal.timeout(c)}:{},headers:{"content-type":"application/json",...a()?{"x-cop-token":a()}:{},...null!=(i=null==e?void 0:e.headers)?i:{}}})}catch(e){if("TimeoutError"===e.name)throw Error("The API did not answer within ".concat(Math.round((null!=c?c:0)/1e3)," s (").concat(t.split("?")[0],"). It may be busy; try again."));throw e}if(!o.ok){let t="".concat(o.status," ").concat(o.statusText);try{let e=await o.json();(null==e?void 0:e.message)&&(t=Array.isArray(e.message)?e.message.join("; "):e.message)}catch(t){}throw Error(t)}let r=await o.text();return r?JSON.parse(r):void 0}let h={health:()=>m("/health"),doctor:()=>m("/doctor"),settings:()=>m("/settings"),saveSettings:t=>m("/settings",{method:"PUT",body:JSON.stringify(t)}),level1:()=>m("/level1"),setLevel1:t=>m("/level1",{method:"PUT",body:JSON.stringify({content:t})}),resetLevel1:()=>m("/level1",{method:"DELETE"}),presets:()=>m("/presets"),savePreset:(t,e)=>m("/presets/".concat(encodeURIComponent(t)),{method:"PUT",body:JSON.stringify({content:e})}),deletePreset:t=>m("/presets/".concat(encodeURIComponent(t)),{method:"DELETE"}),personas:()=>m("/personas"),savePersona:(t,e)=>m("/personas/".concat(encodeURIComponent(t)),{method:"PUT",body:JSON.stringify({content:e})}),deletePersona:t=>m("/personas/".concat(encodeURIComponent(t)),{method:"DELETE"}),sessions:()=>m("/sessions"),reorderSessions:t=>m("/sessions-order",{method:"PUT",body:JSON.stringify({ids:t})}),metrics:()=>m("/metrics"),preparePreview:function(t){let e=!(arguments.length>1)||void 0===arguments[1]||arguments[1];return m("/repo/prepare/preview",{method:"POST",body:JSON.stringify({dir:t,fetch:e})})},prepareProject:(t,e)=>m("/repo/prepare",{method:"POST",body:JSON.stringify({dir:t,fingerprint:e})}),session:t=>m("/sessions/".concat(t)),createSession:(t,e)=>m("/sessions",{method:"POST",body:JSON.stringify({name:t,projectDir:e})}),updateSession:(t,e)=>m("/sessions/".concat(t),{method:"PUT",body:JSON.stringify(e)}),deleteSession:t=>m("/sessions/".concat(t),{method:"DELETE"}),addTask:(t,e)=>m("/sessions/".concat(t,"/tasks"),{method:"POST",body:JSON.stringify(e)}),updateTask:(t,e,o)=>m("/sessions/".concat(t,"/tasks/").concat(e),{method:"PUT",body:JSON.stringify(o)}),deleteTask:(t,e)=>m("/sessions/".concat(t,"/tasks/").concat(e),{method:"DELETE"}),continueTask:(t,e)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/continue"),{method:"POST",body:"{}"}),rerunTask:function(t,e){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return m("/sessions/".concat(t,"/tasks/").concat(e,"/rerun"),{method:"POST",body:JSON.stringify({...o,...n.buildOnFinished?{buildOnFinished:!0}:{}})})},taskChanges:(t,e,o)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/changes").concat(o?"?run=".concat(encodeURIComponent(o)):"")),taskChangeFile:(t,e,o,n)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/changes/file?path=").concat(encodeURIComponent(o)).concat(n?"&run=".concat(encodeURIComponent(n)):"")),taskStory:(t,e,o)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/story").concat(o?"?run=".concat(encodeURIComponent(o)):"")),taskFiles:(t,e,o)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/files").concat(o?"?run=".concat(encodeURIComponent(o)):"")),taskLogUrl:(t,e,o)=>"".concat(n,"/sessions/").concat(t,"/tasks/").concat(e,"/log").concat(o?"?run=".concat(encodeURIComponent(o)):""),taskFileUrl:(t,e,o,s,c)=>"".concat(n,"/sessions/").concat(t,"/tasks/").concat(e,"/files/").concat(o,"/").concat(encodeURIComponent(s)).concat(c?"?run=".concat(encodeURIComponent(c)):""),saveTaskLog:(t,e,o)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/log").concat(o?"?run=".concat(encodeURIComponent(o)):""),{method:"POST",body:"{}"}),saveTaskFile:(t,e,o,n,s)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/files/").concat(o,"/").concat(encodeURIComponent(n)).concat(s?"?run=".concat(encodeURIComponent(s)):""),{method:"POST",body:"{}"}),start:(t,e,o)=>m("/sessions/".concat(t,"/start"),{method:"POST",body:JSON.stringify({mode:e,name:o})}),stop:t=>m("/sessions/".concat(t,"/stop"),{method:"POST",body:"{}"}),approvals:t=>m("/approvals".concat(t?"?session=".concat(encodeURIComponent(t)):"")),decide:(t,e)=>m("/approvals/".concat(t),{method:"POST",body:JSON.stringify({action:e})}),setRunMode:(t,e)=>m("/sessions/".concat(t,"/mode"),{method:"POST",body:JSON.stringify({mode:e})}),streamUrl:t=>i("".concat(n,"/sessions/").concat(t,"/stream")),batch:()=>m("/batch").then(t=>null!=t?t:null),startBatch:(t,e,o,n,s,c,a)=>m("/batch/start",{method:"POST",body:JSON.stringify({sessionIds:t,mode:e,onFailure:o,model:n,reviewModel:s,name:c,taskIds:a})}),suggestedRunName:t=>m("/batch/name?sessions=".concat(encodeURIComponent(t.join(",")))),stopBatch:()=>m("/batch/stop",{method:"POST",body:"{}"}),pauseBatch:()=>m("/batch/pause",{method:"POST",body:"{}"}),resumeBatch:()=>m("/batch/resume",{method:"POST",body:"{}"}),planBrief:t=>m("/plan/brief?lang=".concat(encodeURIComponent(t))),context:(t,e)=>m("/context/".concat(t,"?lang=").concat(encodeURIComponent(e))),setContext:(t,e)=>m("/context/".concat(t),{method:"PUT",body:JSON.stringify({content:e})}),resetContext:(t,e)=>m("/context/".concat(t,"?lang=").concat(encodeURIComponent(e)),{method:"DELETE"}),checkPlan:t=>m("/plan/check",{method:"POST",body:JSON.stringify({text:t})}),importPlan:t=>m("/plan/import",{method:"POST",body:JSON.stringify({text:t})}),browseFolder:t=>m("/browse-folder",{method:"POST",body:JSON.stringify({start:t})},{timeoutMs:null}),tasks:()=>m("/tasks"),activity:()=>m("/activity"),downloadBundle:async t=>{var e,o,s;let c=await fetch("".concat(n,"/export/bundle"),{method:"POST",headers:{"content-type":"application/json",...a()?{"x-cop-token":a()}:{}},body:JSON.stringify({tasks:t})});if(!c.ok)throw Error(await c.text()||"".concat(c.status," ").concat(c.statusText));let i=null!=(s=c.headers.get("content-disposition"))?s:"",r=null==(e=/filename\*=UTF-8''([^;]+)/i.exec(i))?void 0:e[1],d=null==(o=/filename="([^"]+)"/i.exec(i))?void 0:o[1],l=null!=d?d:"copilot-operator-bundle.json";if(r)try{l=decodeURIComponent(r)}catch(t){}let u=URL.createObjectURL(await c.blob()),m=document.createElement("a");return m.href=u,m.download=l,document.body.appendChild(m),m.click(),m.remove(),setTimeout(()=>URL.revokeObjectURL(u),1e4),l},exportUrl:(t,e)=>{let o=new URLSearchParams;return e.run&&o.set("run",e.run),e.session&&o.set("session",e.session),e.task&&o.set("task",e.task),i("".concat(n,"/export/").concat(t,"?").concat(o.toString()))},debugExportUrl:t=>i("".concat(n,"/debug/export").concat(t.length>0?"?sessions=".concat(encodeURIComponent(t.join(","))):"")),vcsStatus:t=>m("/sessions/".concat(t,"/vcs")),runVcs:t=>m("/batch/vcs?ids=".concat(encodeURIComponent(t.join(",")))),runVcsPrepare:function(t,e,o){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return m("/batch/vcs/prepare",{method:"POST",body:JSON.stringify({sessionIds:t,repoDir:e,action:o,choices:n})})},vcsSnapshot:(t,e)=>m("/sessions/".concat(t,"/vcs/snapshot"),{method:"POST",body:JSON.stringify({choices:e})}),restorePreview:(t,e)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/restore")),restore:(t,e)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/restore"),{method:"POST",body:"{}"}),restartPlan:(t,e)=>m("/sessions/".concat(t,"/tasks/").concat(e,"/restart")),restartFrom:function(t,e){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return m("/sessions/".concat(t,"/tasks/").concat(e,"/restart"),{method:"POST",body:JSON.stringify(o)})},repoCheck:t=>m("/repo?dir=".concat(encodeURIComponent(t))),project:()=>m("/project"),setProject:t=>m("/project",{method:"PUT",body:JSON.stringify(t)}),models:()=>m("/models"),setDefaultModel:t=>m("/models/default",{method:"PUT",body:JSON.stringify({model:t})}),setDefaultReviewModel:t=>m("/models/review-default",{method:"PUT",body:JSON.stringify({model:t})}),refreshModels:()=>m("/models/refresh",{method:"POST",body:"{}"},{timeoutMs:null}),login:t=>m("/login",{method:"POST",body:JSON.stringify({account:(null==t?void 0:t.trim())||void 0})},{timeoutMs:null})};function p(t){return t<1024?"".concat(t," B"):t<1048576?"".concat((t/1024).toFixed(1)," KB"):"".concat((t/1048576).toFixed(1)," MB")}function y(t){if(void 0===t)return"";let e=Math.round(t/1e3);if(e<60)return"".concat(e,"s");let o=Math.floor(e/60);return o<60?"".concat(o,"m ").concat(e%60,"s"):"".concat(Math.floor(o/60),"h ").concat(o%60,"m")}}}]);