@co0ontty/wand 4.55.3 → 4.56.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 (55) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/github-connector.d.ts +22 -0
  3. package/dist/github-connector.js +117 -0
  4. package/dist/missions.js +42 -9
  5. package/dist/server-github-routes.d.ts +10 -0
  6. package/dist/server-github-routes.js +239 -0
  7. package/dist/server-settings-routes.d.ts +2 -0
  8. package/dist/server-settings-routes.js +1 -0
  9. package/dist/server-task-routes.d.ts +4 -0
  10. package/dist/server-task-routes.js +99 -0
  11. package/dist/server-workspace-routes.js +70 -27
  12. package/dist/server.js +25 -0
  13. package/dist/storage.d.ts +42 -0
  14. package/dist/storage.js +223 -0
  15. package/dist/structured-provider-common.js +2 -1
  16. package/dist/task-types.d.ts +19 -0
  17. package/dist/task-types.js +1 -0
  18. package/dist/taskboard-bridge.d.ts +11 -0
  19. package/dist/taskboard-bridge.js +360 -0
  20. package/dist/web-ui/content/scripts.js +123 -127
  21. package/dist/web-ui/content/styles.css +1 -1
  22. package/dist/web-ui/embedded-assets.js +2 -2
  23. package/dist/web-ui/index.js +1 -0
  24. package/package.json +4 -2
  25. package/vendor/codex-taskboard/LICENSE +201 -0
  26. package/vendor/codex-taskboard/server/ai-chat-catalog.mjs +1031 -0
  27. package/vendor/codex-taskboard/server/ai-chat-process.mjs +462 -0
  28. package/vendor/codex-taskboard/server/ai-chat.mjs +1237 -0
  29. package/vendor/codex-taskboard/server/ai-turn-owner.mjs +39 -0
  30. package/vendor/codex-taskboard/server/app.mjs +3211 -0
  31. package/vendor/codex-taskboard/server/cloud-config.mjs +188 -0
  32. package/vendor/codex-taskboard/server/cloud-proxy.mjs +310 -0
  33. package/vendor/codex-taskboard/server/codex-app-server.mjs +376 -0
  34. package/vendor/codex-taskboard/server/codex-slash-commands-0.139.0.json +62 -0
  35. package/vendor/codex-taskboard/server/database.mjs +2845 -0
  36. package/vendor/codex-taskboard/server/index.mjs +41 -0
  37. package/vendor/codex-taskboard/server/jira-config.mjs +181 -0
  38. package/vendor/codex-taskboard/server/jira-integration.mjs +487 -0
  39. package/vendor/codex-taskboard/server/project-summary.mjs +159 -0
  40. package/vendor/codex-taskboard/shared/api-fields.mjs +163 -0
  41. package/vendor/codex-taskboard/shared/codex-environment.mjs +5 -0
  42. package/vendor/codex-taskboard/shared/codex-executable.mjs +77 -0
  43. package/vendor/codex-taskboard/shared/codex-permissions.mjs +9 -0
  44. package/vendor/codex-taskboard/shared/composer-reference.d.mts +19 -0
  45. package/vendor/codex-taskboard/shared/composer-reference.mjs +90 -0
  46. package/vendor/codex-taskboard/shared/domain.mjs +34 -0
  47. package/vendor/codex-taskboard/shared/executable-command.mjs +13 -0
  48. package/vendor/codex-taskboard/shared/process-tree.mjs +27 -0
  49. package/vendor/codex-taskboard/shared/task-input.mjs +308 -0
  50. package/vendor/codex-taskboard/shared/task-records.mjs +199 -0
  51. package/vendor/codex-taskboard/shared/task-relations.mjs +55 -0
  52. package/vendor/codex-taskboard/shared/taskboard-automation.mjs +277 -0
  53. package/vendor/codex-taskboard/skills/manage-taskboard/SKILL.md +45 -0
  54. package/vendor/codex-taskboard/skills/manage-taskboard/agents/openai.yaml +4 -0
  55. package/vendor/codex-taskboard/skills/manage-taskboard/references/cli.md +211 -0
@@ -0,0 +1,376 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+
4
+ import { withoutTaskboardLauncherEnvironment } from "../shared/codex-environment.mjs";
5
+ import { executableCommand } from "../shared/executable-command.mjs";
6
+
7
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
8
+ const MAX_STDOUT_BUFFER = 4 * 1024 * 1024;
9
+ const STDERR_LIMIT = 16 * 1024;
10
+
11
+ export class CodexAppServerError extends Error {
12
+ constructor(message, details) {
13
+ super(message);
14
+ this.name = "CodexAppServerError";
15
+ this.details = details;
16
+ }
17
+ }
18
+
19
+ export class CodexAppServer {
20
+ constructor({ executable, processEnv = process.env, requestTimeoutMs } = {}) {
21
+ this.executable = executable;
22
+ this.processEnv = withoutTaskboardLauncherEnvironment(processEnv);
23
+ this.requestTimeoutMs = requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
24
+ this.child = null;
25
+ this.starting = null;
26
+ this.closing = false;
27
+ this.nextRequestId = 1;
28
+ this.pending = new Map();
29
+ this.listeners = new Set();
30
+ this.terminatedChildren = new WeakSet();
31
+ }
32
+
33
+ subscribe(listener) {
34
+ this.listeners.add(listener);
35
+ return () => this.listeners.delete(listener);
36
+ }
37
+
38
+ async listSkills(workspacePath, { forceReload = false } = {}) {
39
+ const result = await this.request("skills/list", {
40
+ cwds: [workspacePath],
41
+ forceReload,
42
+ });
43
+ return Array.isArray(result?.data) ? result.data : [];
44
+ }
45
+
46
+ startThread(params) {
47
+ return this.request("thread/start", params);
48
+ }
49
+
50
+ resumeThread(params) {
51
+ return this.request("thread/resume", params);
52
+ }
53
+
54
+ startTurn(params) {
55
+ return this.request("turn/start", params);
56
+ }
57
+
58
+ interruptTurn(params) {
59
+ return this.request("turn/interrupt", params);
60
+ }
61
+
62
+ compactThread(threadId) {
63
+ return this.request("thread/compact/start", { threadId });
64
+ }
65
+
66
+ async request(method, params) {
67
+ const child = await this.#ensureStarted();
68
+ return this.#sendRequest(child, method, params);
69
+ }
70
+
71
+ async close() {
72
+ this.closing = true;
73
+ const child = this.child;
74
+ this.starting = null;
75
+ const error = new CodexAppServerError("Codex app-server closed");
76
+ if (child) this.#handleExit(child, error);
77
+ this.#rejectPending(error);
78
+ this.listeners.clear();
79
+ if (!child || child.exitCode !== null || child.signalCode !== null) return;
80
+ child.stdin.end();
81
+ await Promise.race([
82
+ new Promise((resolve) => child.once("exit", resolve)),
83
+ new Promise((resolve) => {
84
+ const timer = setTimeout(resolve, 1_000);
85
+ timer.unref();
86
+ }),
87
+ ]);
88
+ if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
89
+ }
90
+
91
+ async #ensureStarted() {
92
+ if (this.closing) throw new CodexAppServerError("Codex app-server is closing");
93
+ if (this.starting) return this.starting;
94
+ if (this.child && this.child.exitCode === null && this.child.signalCode === null) return this.child;
95
+
96
+ const starting = new Promise((resolve, reject) => {
97
+ const command = executableCommand(this.executable, ["app-server", "--stdio"]);
98
+ const child = spawn(command.executable, command.args, {
99
+ env: this.processEnv,
100
+ stdio: ["pipe", "pipe", "pipe"],
101
+ });
102
+ this.child = child;
103
+ const output = { stdoutBuffer: "", stderr: "" };
104
+ child.stdout.setEncoding("utf8");
105
+ child.stderr.setEncoding("utf8");
106
+ child.stdout.on("data", (chunk) => this.#handleStdout(child, output, chunk));
107
+ child.stderr.on("data", (chunk) => {
108
+ output.stderr = `${output.stderr}${chunk}`.slice(-STDERR_LIMIT);
109
+ });
110
+ child.stdin.on("error", (error) => this.#handleExit(child, error));
111
+ child.stdout.on("error", (error) => this.#handleExit(child, error));
112
+ child.stderr.on("error", (error) => this.#handleExit(child, error));
113
+ child.once("error", (error) => {
114
+ this.#handleExit(child, error);
115
+ reject(error);
116
+ });
117
+ child.once("exit", (code, signal) => {
118
+ const suffix = output.stderr.trim() ? `: ${output.stderr.trim()}` : "";
119
+ const error = new CodexAppServerError(
120
+ `Codex app-server exited (${signal || code})${suffix}`,
121
+ { code, signal },
122
+ );
123
+ this.#handleExit(child, error);
124
+ });
125
+ child.once("spawn", () => {
126
+ this.#sendRequest(child, "initialize", {
127
+ clientInfo: {
128
+ name: "codex-taskboard",
129
+ title: "Codex Taskboard",
130
+ version: "1.0.1",
131
+ },
132
+ capabilities: {
133
+ experimentalApi: true,
134
+ requestAttestation: false,
135
+ },
136
+ }).then(() => {
137
+ this.#sendNotification(child, "initialized");
138
+ resolve(child);
139
+ }, reject);
140
+ });
141
+ }).finally(() => {
142
+ if (this.starting === starting) this.starting = null;
143
+ });
144
+ this.starting = starting;
145
+ return starting;
146
+ }
147
+
148
+ #sendRequest(child, method, params) {
149
+ if (!child || child !== this.child || child.exitCode !== null || child.signalCode !== null) {
150
+ return Promise.reject(new CodexAppServerError("Codex app-server is not running"));
151
+ }
152
+ const id = this.nextRequestId;
153
+ this.nextRequestId += 1;
154
+ return new Promise((resolve, reject) => {
155
+ const timer = setTimeout(() => {
156
+ this.pending.delete(id);
157
+ reject(new CodexAppServerError(`Codex app-server request '${method}' timed out`));
158
+ }, this.requestTimeoutMs);
159
+ timer.unref();
160
+ this.pending.set(id, { child, method, resolve, reject, timer });
161
+ child.stdin.write(`${JSON.stringify({ id, method, params })}\n`, (error) => {
162
+ if (error) this.#handleExit(child, error);
163
+ });
164
+ });
165
+ }
166
+
167
+ #sendNotification(child, method) {
168
+ child.stdin.write(`${JSON.stringify({ method })}\n`, (error) => {
169
+ if (error) this.#handleExit(child, error);
170
+ });
171
+ }
172
+
173
+ #handleStdout(child, output, chunk) {
174
+ if (child !== this.child) return;
175
+ output.stdoutBuffer += chunk;
176
+ if (output.stdoutBuffer.length > MAX_STDOUT_BUFFER) {
177
+ this.#handleExit(child, new CodexAppServerError("Codex app-server output exceeded its limit"));
178
+ return;
179
+ }
180
+ let newlineIndex = output.stdoutBuffer.indexOf("\n");
181
+ while (newlineIndex >= 0 && child === this.child) {
182
+ const line = output.stdoutBuffer.slice(0, newlineIndex).trim();
183
+ output.stdoutBuffer = output.stdoutBuffer.slice(newlineIndex + 1);
184
+ if (line) {
185
+ try {
186
+ this.#handleMessage(child, JSON.parse(line));
187
+ } catch (error) {
188
+ console.error("Codex app-server returned invalid JSON", error);
189
+ }
190
+ }
191
+ newlineIndex = output.stdoutBuffer.indexOf("\n");
192
+ }
193
+ }
194
+
195
+ #handleMessage(child, message) {
196
+ if (message && Object.hasOwn(message, "id") && !message.method) {
197
+ const pending = this.pending.get(message.id);
198
+ if (!pending || pending.child !== child) return;
199
+ this.pending.delete(message.id);
200
+ clearTimeout(pending.timer);
201
+ if (message.error) {
202
+ pending.reject(new CodexAppServerError(
203
+ `Codex app-server rejected '${pending.method}': ${message.error.message ?? "unknown error"}`,
204
+ message.error,
205
+ ));
206
+ } else {
207
+ pending.resolve(message.result);
208
+ }
209
+ return;
210
+ }
211
+ if (typeof message?.method !== "string") return;
212
+ if (Object.hasOwn(message, "id")) {
213
+ child.stdin.write(`${JSON.stringify({
214
+ id: message.id,
215
+ error: { code: -32601, message: `Unsupported server request '${message.method}'` },
216
+ })}\n`, (error) => {
217
+ if (error) this.#handleExit(child, error);
218
+ });
219
+ return;
220
+ }
221
+ this.#notify(message, child);
222
+ }
223
+
224
+ #notify(message, child) {
225
+ for (const listener of this.listeners) {
226
+ try {
227
+ listener(message, child);
228
+ } catch (error) {
229
+ console.error("Codex app-server notification handler failed", error);
230
+ }
231
+ }
232
+ }
233
+
234
+ #handleExit(child, error) {
235
+ if (this.terminatedChildren.has(child)) return;
236
+ this.terminatedChildren.add(child);
237
+ if (this.child === child) {
238
+ this.child = null;
239
+ this.starting = null;
240
+ }
241
+ this.#rejectPending(error, child);
242
+ if (child.exitCode === null && child.signalCode === null) child.kill("SIGTERM");
243
+ this.#notify({
244
+ method: "app-server/terminated",
245
+ params: { message: error.message },
246
+ }, child);
247
+ }
248
+
249
+ #rejectPending(error, child) {
250
+ for (const [id, pending] of this.pending) {
251
+ if (child && pending.child !== child) continue;
252
+ this.pending.delete(id);
253
+ clearTimeout(pending.timer);
254
+ pending.reject(error);
255
+ }
256
+ }
257
+ }
258
+
259
+ export class CodexHostAppServer {
260
+ constructor({ hostId, ipc = process, requestTimeoutMs } = {}) {
261
+ this.hostId = hostId;
262
+ this.ipc = ipc;
263
+ this.requestTimeoutMs = requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
264
+ this.pending = new Map();
265
+ this.listeners = new Set();
266
+ this.closed = false;
267
+ this.handleMessage = (message) => this.#handleMessage(message);
268
+ this.ipc.on?.("message", this.handleMessage);
269
+ }
270
+
271
+ subscribe(listener) {
272
+ this.listeners.add(listener);
273
+ return () => this.listeners.delete(listener);
274
+ }
275
+
276
+ async listSkills(workspacePath, { forceReload = false } = {}) {
277
+ const result = await this.request("skills/list", {
278
+ cwds: [workspacePath],
279
+ forceReload,
280
+ });
281
+ return Array.isArray(result?.data) ? result.data : [];
282
+ }
283
+
284
+ startThread(params) {
285
+ return this.request("thread/start", params);
286
+ }
287
+
288
+ resumeThread(params) {
289
+ return this.request("thread/resume", params);
290
+ }
291
+
292
+ startTurn(params) {
293
+ return this.request("turn/start", params);
294
+ }
295
+
296
+ interruptTurn(params) {
297
+ return this.request("turn/interrupt", params);
298
+ }
299
+
300
+ compactThread(threadId) {
301
+ return this.request("thread/compact/start", { threadId });
302
+ }
303
+
304
+ request(method, params) {
305
+ if (this.closed || typeof this.ipc.send !== "function" || this.ipc.connected === false) {
306
+ return Promise.reject(new CodexAppServerError("Codex host bridge is unavailable"));
307
+ }
308
+ const requestId = randomUUID();
309
+ return new Promise((resolve, reject) => {
310
+ const timer = setTimeout(() => {
311
+ this.pending.delete(requestId);
312
+ reject(new CodexAppServerError(`Codex host request '${method}' timed out`));
313
+ }, this.requestTimeoutMs);
314
+ timer.unref();
315
+ this.pending.set(requestId, { method, resolve, reject, timer });
316
+ this.ipc.send({
317
+ type: "taskboard:codex-app-server-request",
318
+ requestId,
319
+ hostId: this.hostId,
320
+ method,
321
+ params,
322
+ }, (error) => {
323
+ if (!error) return;
324
+ clearTimeout(timer);
325
+ this.pending.delete(requestId);
326
+ reject(error);
327
+ });
328
+ });
329
+ }
330
+
331
+ async close() {
332
+ if (this.closed) return;
333
+ this.closed = true;
334
+ this.ipc.off?.("message", this.handleMessage);
335
+ this.#rejectPending(new CodexAppServerError("Codex host bridge closed"));
336
+ this.listeners.clear();
337
+ }
338
+
339
+ #handleMessage(message) {
340
+ if (!message || typeof message !== "object" || message.hostId !== this.hostId) return;
341
+ if (message.type === "taskboard:codex-app-server-response") {
342
+ const pending = this.pending.get(message.requestId);
343
+ if (!pending) return;
344
+ this.pending.delete(message.requestId);
345
+ clearTimeout(pending.timer);
346
+ if (message.error) {
347
+ pending.reject(new CodexAppServerError(
348
+ `Codex host rejected '${pending.method}': ${message.error}`,
349
+ ));
350
+ } else {
351
+ pending.resolve(message.result);
352
+ }
353
+ return;
354
+ }
355
+ if (
356
+ message.type !== "taskboard:codex-app-server-notification"
357
+ || typeof message.method !== "string"
358
+ ) return;
359
+ const notification = { method: message.method, params: message.params };
360
+ for (const listener of this.listeners) {
361
+ try {
362
+ listener(notification);
363
+ } catch (error) {
364
+ console.error("Codex host notification handler failed", error);
365
+ }
366
+ }
367
+ }
368
+
369
+ #rejectPending(error) {
370
+ for (const pending of this.pending.values()) {
371
+ clearTimeout(pending.timer);
372
+ pending.reject(error);
373
+ }
374
+ this.pending.clear();
375
+ }
376
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "codexVersion": "0.139.0",
3
+ "source": "codex-rs/tui/src/slash_command.rs",
4
+ "commands": [
5
+ { "id": "model", "description": "choose what model and reasoning effort to use" },
6
+ { "id": "ide", "description": "include current selection, open files, and other context from your IDE", "supportsInlineArgs": true },
7
+ { "id": "permissions", "description": "choose what Codex is allowed to do" },
8
+ { "id": "keymap", "description": "remap TUI shortcuts", "supportsInlineArgs": true },
9
+ { "id": "vim", "description": "toggle Vim mode for the composer" },
10
+ { "id": "setup-default-sandbox", "description": "set up elevated agent sandbox" },
11
+ { "id": "sandbox-add-read-dir", "description": "let sandbox read a directory: /sandbox-add-read-dir <absolute_path>", "supportsInlineArgs": true, "platforms": ["win32"] },
12
+ { "id": "experimental", "description": "toggle experimental features" },
13
+ { "id": "approve", "description": "approve one retry of a recent auto-review denial" },
14
+ { "id": "memories", "description": "configure memory use and generation" },
15
+ { "id": "skills", "description": "use skills to improve how Codex performs specific tasks" },
16
+ { "id": "import", "description": "import setup, this project, and recent chats from Claude Code" },
17
+ { "id": "hooks", "description": "view and manage lifecycle hooks" },
18
+ { "id": "review", "description": "review my current changes and find issues", "supportsInlineArgs": true },
19
+ { "id": "rename", "description": "rename the current thread", "supportsInlineArgs": true },
20
+ { "id": "new", "description": "start a new chat during a conversation", "supportsInlineArgs": true },
21
+ { "id": "archive", "description": "archive this session and exit" },
22
+ { "id": "delete", "description": "permanently delete this session and exit" },
23
+ { "id": "resume", "description": "resume a saved chat", "supportsInlineArgs": true },
24
+ { "id": "fork", "description": "fork the current chat", "supportsInlineArgs": true },
25
+ { "id": "app", "description": "continue this session in the Desktop app", "platforms": ["darwin", "win32"] },
26
+ { "id": "init", "description": "create an AGENTS.md file with instructions for Codex" },
27
+ { "id": "compact", "description": "summarize conversation to prevent hitting the context limit" },
28
+ { "id": "plan", "description": "switch to Plan mode", "supportsInlineArgs": true },
29
+ { "id": "goal", "description": "set or view the goal for a long-running task", "supportsInlineArgs": true },
30
+ { "id": "agent", "description": "switch the active agent thread" },
31
+ { "id": "side", "description": "start a side conversation in an ephemeral fork", "supportsInlineArgs": true },
32
+ { "id": "btw", "description": "start a side conversation in an ephemeral fork", "supportsInlineArgs": true },
33
+ { "id": "copy", "description": "copy last response as markdown", "excludedPlatforms": ["android"] },
34
+ { "id": "export", "description": "export the conversation as markdown", "supportsInlineArgs": true },
35
+ { "id": "raw", "description": "toggle raw scrollback mode for copy-friendly terminal selection", "supportsInlineArgs": true },
36
+ { "id": "diff", "description": "show git diff (including untracked files)" },
37
+ { "id": "mention", "description": "mention a file" },
38
+ { "id": "status", "description": "show current session configuration and token usage" },
39
+ { "id": "usage", "description": "view account usage or use a usage limit reset", "supportsInlineArgs": true },
40
+ { "id": "debug-config", "description": "show config layers and requirement sources for debugging" },
41
+ { "id": "title", "description": "configure which items appear in the terminal title" },
42
+ { "id": "statusline", "description": "configure which items appear in the status line" },
43
+ { "id": "theme", "description": "choose a syntax highlighting theme" },
44
+ { "id": "pets", "description": "choose or hide the terminal pet", "supportsInlineArgs": true },
45
+ { "id": "mcp", "description": "list configured MCP tools; use /mcp verbose for details", "supportsInlineArgs": true },
46
+ { "id": "apps", "description": "manage apps" },
47
+ { "id": "plugins", "description": "browse plugins" },
48
+ { "id": "logout", "description": "log out of Codex" },
49
+ { "id": "quit", "description": "exit Codex" },
50
+ { "id": "exit", "description": "exit Codex" },
51
+ { "id": "feedback", "description": "send logs to maintainers" },
52
+ { "id": "rollout", "description": "print the rollout file path", "debugOnly": true },
53
+ { "id": "ps", "description": "list background terminals" },
54
+ { "id": "stop", "description": "stop all background terminals" },
55
+ { "id": "clear", "description": "clear the terminal and start a new chat", "supportsInlineArgs": true },
56
+ { "id": "personality", "description": "choose a communication style for Codex" },
57
+ { "id": "test-approval", "description": "test approval request", "debugOnly": true },
58
+ { "id": "subagents", "description": "switch the active agent thread" },
59
+ { "id": "debug-m-drop", "description": "DO NOT USE", "debugOnly": true },
60
+ { "id": "debug-m-update", "description": "DO NOT USE", "debugOnly": true }
61
+ ]
62
+ }