@exaudeus/workrail 3.31.1 → 3.33.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 (82) hide show
  1. package/dist/cli/commands/index.d.ts +1 -0
  2. package/dist/cli/commands/index.js +3 -1
  3. package/dist/cli/commands/worktrain-await.js +11 -9
  4. package/dist/cli/commands/worktrain-daemon-install.d.ts +35 -0
  5. package/dist/cli/commands/worktrain-daemon-install.js +291 -0
  6. package/dist/cli/commands/worktrain-daemon.d.ts +31 -0
  7. package/dist/cli/commands/worktrain-daemon.js +272 -0
  8. package/dist/cli/commands/worktrain-spawn.js +11 -9
  9. package/dist/cli-worktrain.js +329 -0
  10. package/dist/cli.js +4 -22
  11. package/dist/console/standalone-console.d.ts +28 -0
  12. package/dist/console/standalone-console.js +142 -0
  13. package/dist/{console/assets/index-6H9DeFxj.js → console-ui/assets/index-BuJFLLfY.js} +1 -1
  14. package/dist/{console → console-ui}/index.html +1 -1
  15. package/dist/daemon/agent-loop.d.ts +26 -0
  16. package/dist/daemon/agent-loop.js +53 -2
  17. package/dist/daemon/daemon-events.d.ts +103 -0
  18. package/dist/daemon/daemon-events.js +56 -0
  19. package/dist/daemon/workflow-runner.d.ts +6 -3
  20. package/dist/daemon/workflow-runner.js +229 -33
  21. package/dist/infrastructure/session/HttpServer.js +133 -34
  22. package/dist/manifest.json +134 -70
  23. package/dist/mcp/output-schemas.d.ts +30 -30
  24. package/dist/mcp/transports/bridge-events.d.ts +4 -0
  25. package/dist/mcp/transports/fatal-exit.js +4 -0
  26. package/dist/mcp/transports/http-entry.js +2 -0
  27. package/dist/mcp/transports/stdio-entry.js +26 -6
  28. package/dist/mcp/v2/tools.d.ts +4 -4
  29. package/dist/trigger/adapters/github-poller.d.ts +44 -0
  30. package/dist/trigger/adapters/github-poller.js +190 -0
  31. package/dist/trigger/adapters/gitlab-poller.d.ts +27 -0
  32. package/dist/trigger/adapters/gitlab-poller.js +81 -0
  33. package/dist/trigger/delivery-client.d.ts +2 -1
  34. package/dist/trigger/delivery-client.js +4 -1
  35. package/dist/trigger/index.d.ts +4 -1
  36. package/dist/trigger/index.js +5 -1
  37. package/dist/trigger/polled-event-store.d.ts +22 -0
  38. package/dist/trigger/polled-event-store.js +173 -0
  39. package/dist/trigger/polling-scheduler.d.ts +20 -0
  40. package/dist/trigger/polling-scheduler.js +249 -0
  41. package/dist/trigger/trigger-listener.d.ts +5 -0
  42. package/dist/trigger/trigger-listener.js +53 -4
  43. package/dist/trigger/trigger-router.d.ts +4 -2
  44. package/dist/trigger/trigger-router.js +7 -4
  45. package/dist/trigger/trigger-store.js +114 -33
  46. package/dist/trigger/types.d.ts +17 -1
  47. package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +224 -224
  48. package/dist/v2/durable-core/schemas/session/events.d.ts +42 -42
  49. package/dist/v2/durable-core/schemas/session/manifest.d.ts +6 -6
  50. package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
  51. package/dist/v2/durable-core/tokens/payloads.d.ts +52 -52
  52. package/dist/v2/usecases/console-routes.js +3 -3
  53. package/dist/v2/usecases/console-service.js +133 -9
  54. package/dist/v2/usecases/console-types.d.ts +7 -0
  55. package/docs/design/daemon-conversation-logging-plan.md +98 -0
  56. package/docs/design/daemon-conversation-logging-review.md +55 -0
  57. package/docs/design/daemon-conversation-logging.md +129 -0
  58. package/docs/design/github-polling-adapter-design-candidates.md +226 -0
  59. package/docs/design/github-polling-adapter-design-review-findings.md +131 -0
  60. package/docs/design/github-polling-adapter-implementation-plan.md +284 -0
  61. package/docs/design/implementation_plan.md +192 -0
  62. package/docs/design/workflow-id-validation-at-startup.md +146 -0
  63. package/docs/design/workflow-id-validation-design-review.md +87 -0
  64. package/docs/design/workflow-id-validation-implementation-plan.md +185 -0
  65. package/docs/design/worktrain-system-prompt-report-issue-candidates.md +135 -0
  66. package/docs/design/worktrain-system-prompt-report-issue-design-review.md +73 -0
  67. package/docs/ideas/backlog.md +465 -0
  68. package/package.json +1 -1
  69. package/workflows/architecture-scalability-audit.json +1 -1
  70. package/workflows/bug-investigation.agentic.v2.json +3 -3
  71. package/workflows/coding-task-workflow-agentic.json +32 -32
  72. package/workflows/coding-task-workflow-agentic.lean.v2.json +1 -1
  73. package/workflows/coding-task-workflow-agentic.v2.json +7 -7
  74. package/workflows/mr-review-workflow.agentic.v2.json +21 -12
  75. package/workflows/personal-learning-materials-creation-branched.json +2 -2
  76. package/workflows/production-readiness-audit.json +1 -1
  77. package/workflows/relocation-workflow-us.json +2 -2
  78. package/workflows/ui-ux-design-workflow.json +14 -14
  79. package/workflows/workflow-for-workflows.json +3 -3
  80. package/workflows/workflow-for-workflows.v2.json +2 -2
  81. package/workflows/wr.discovery.json +1 -1
  82. /package/dist/{console → console-ui}/assets/index-8dh0Psu-.css +0 -0
package/dist/cli.js CHANGED
@@ -190,7 +190,7 @@ program
190
190
  .option('-w, --workspace <path>', 'Path to workspace containing triggers.yml')
191
191
  .action(async (options) => {
192
192
  const { startTriggerListener } = await Promise.resolve().then(() => __importStar(require('./trigger/trigger-listener.js')));
193
- const { startDaemonConsole } = await Promise.resolve().then(() => __importStar(require('./trigger/daemon-console.js')));
193
+ const { DaemonEventEmitter } = await Promise.resolve().then(() => __importStar(require('./daemon/daemon-events.js')));
194
194
  await (0, container_js_1.initializeContainer)({ runtimeMode: { kind: 'cli' } });
195
195
  const { createToolContext } = await Promise.resolve().then(() => __importStar(require('./mcp/server.js')));
196
196
  const { requireV2Context } = await Promise.resolve().then(() => __importStar(require('./mcp/types.js')));
@@ -216,10 +216,12 @@ program
216
216
  console.error('No LLM credentials found. Set AWS_PROFILE (for Bedrock) or ANTHROPIC_API_KEY (for direct Anthropic).');
217
217
  process.exit(1);
218
218
  }
219
+ const emitter = new DaemonEventEmitter();
219
220
  const handle = await startTriggerListener(ctx, {
220
221
  workspacePath,
221
222
  apiKey: apiKey,
222
223
  env: process.env,
224
+ emitter,
223
225
  });
224
226
  if (handle === null) {
225
227
  console.error('Daemon is disabled. Set WORKRAIL_TRIGGERS_ENABLED=true to enable.');
@@ -232,29 +234,9 @@ program
232
234
  console.log(`WorkRail daemon running on port ${handle.port}`);
233
235
  console.log(`Workspace: ${workspacePath}`);
234
236
  console.log('Waiting for webhook triggers...');
235
- const pkg = require('../package.json');
236
- const consoleResult = await startDaemonConsole(ctx, {
237
- triggerRouter: handle.router,
238
- serverVersion: pkg.version,
239
- workflowService: rawCtx.workflowService,
240
- });
241
- let consoleHandle = null;
242
- if (consoleResult.kind === 'ok') {
243
- consoleHandle = consoleResult.value;
244
- }
245
- else if (consoleResult.error.kind === 'port_conflict') {
246
- console.warn(`[DaemonConsole] Port ${consoleResult.error.port} is already held (likely by an MCP server). ` +
247
- `The daemon is running but the console is unavailable. ` +
248
- `Restart the MCP server while the daemon is running to enable the daemon console.`);
249
- }
250
- else {
251
- console.warn(`[DaemonConsole] Could not start console: ${consoleResult.error.message}`);
252
- }
237
+ console.log('Run "worktrain console" in a separate terminal to start the console UI.');
253
238
  const shutdown = async () => {
254
239
  console.log('\nShutting down daemon...');
255
- if (consoleHandle) {
256
- await consoleHandle.stop();
257
- }
258
240
  await handle.stop();
259
241
  process.exit(0);
260
242
  };
@@ -0,0 +1,28 @@
1
+ export interface StandaloneConsoleHandle {
2
+ readonly port: number;
3
+ stop(): Promise<void>;
4
+ }
5
+ export type StandaloneConsoleError = {
6
+ readonly kind: 'port_conflict';
7
+ readonly port: number;
8
+ } | {
9
+ readonly kind: 'io_error';
10
+ readonly message: string;
11
+ };
12
+ export type StandaloneConsoleResult = ({
13
+ readonly kind: 'ok';
14
+ } & StandaloneConsoleHandle) | ({
15
+ readonly kind: 'port_conflict';
16
+ } & {
17
+ readonly port: number;
18
+ }) | ({
19
+ readonly kind: 'io_error';
20
+ } & {
21
+ readonly message: string;
22
+ });
23
+ export interface StartStandaloneConsoleOptions {
24
+ readonly port?: number;
25
+ readonly dataDir?: string;
26
+ readonly lockFilePath?: string;
27
+ }
28
+ export declare function startStandaloneConsole(options?: StartStandaloneConsoleOptions): Promise<StandaloneConsoleResult>;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.startStandaloneConsole = startStandaloneConsole;
40
+ const express_1 = __importDefault(require("express"));
41
+ const cors_1 = __importDefault(require("cors"));
42
+ const http = __importStar(require("node:http"));
43
+ const fs = __importStar(require("node:fs/promises"));
44
+ const path = __importStar(require("node:path"));
45
+ const os = __importStar(require("node:os"));
46
+ const index_js_1 = require("../v2/infra/local/data-dir/index.js");
47
+ const index_js_2 = require("../v2/infra/local/directory-listing/index.js");
48
+ const index_js_3 = require("../v2/infra/local/fs/index.js");
49
+ const index_js_4 = require("../v2/infra/local/sha256/index.js");
50
+ const index_js_5 = require("../v2/infra/local/crypto/index.js");
51
+ const index_js_6 = require("../v2/infra/local/snapshot-store/index.js");
52
+ const index_js_7 = require("../v2/infra/local/pinned-workflow-store/index.js");
53
+ const index_js_8 = require("../v2/infra/local/session-store/index.js");
54
+ const console_service_js_1 = require("../v2/usecases/console-service.js");
55
+ const console_routes_js_1 = require("../v2/usecases/console-routes.js");
56
+ async function startStandaloneConsole(options = {}) {
57
+ const port = options.port ?? 3456;
58
+ const env = process.env;
59
+ const dataRoot = options.dataDir
60
+ ?? env['WORKRAIL_DATA_DIR']
61
+ ?? path.join(os.homedir(), '.workrail', 'data');
62
+ const envWithDataDir = {
63
+ ...env,
64
+ WORKRAIL_DATA_DIR: dataRoot,
65
+ };
66
+ const lockFilePath = options.lockFilePath
67
+ ?? path.join(os.homedir(), '.workrail', 'daemon-console.lock');
68
+ const dataDir = new index_js_1.LocalDataDirV2(envWithDataDir);
69
+ const fsPort = new index_js_3.NodeFileSystemV2();
70
+ const sha256 = new index_js_4.NodeSha256V2();
71
+ const crypto = new index_js_5.NodeCryptoV2();
72
+ const directoryListing = new index_js_2.LocalDirectoryListingV2(fsPort);
73
+ const sessionStore = new index_js_8.LocalSessionEventLogStoreV2(dataDir, fsPort, sha256);
74
+ const snapshotStore = new index_js_6.LocalSnapshotStoreV2(dataDir, fsPort, crypto);
75
+ const pinnedWorkflowStore = new index_js_7.LocalPinnedWorkflowStoreV2(dataDir, fsPort);
76
+ const consoleService = new console_service_js_1.ConsoleService({
77
+ directoryListing,
78
+ dataDir,
79
+ sessionStore,
80
+ snapshotStore,
81
+ pinnedWorkflowStore,
82
+ });
83
+ const app = (0, express_1.default)();
84
+ app.use((0, cors_1.default)({
85
+ origin: '*',
86
+ methods: ['GET', 'HEAD', 'OPTIONS', 'POST', 'DELETE'],
87
+ allowedHeaders: ['Content-Type', 'If-None-Match'],
88
+ }));
89
+ app.set('etag', 'strong');
90
+ const stopWatcher = (0, console_routes_js_1.mountConsoleRoutes)(app, consoleService, undefined, undefined, undefined, undefined, undefined, undefined);
91
+ app.get('/', (_req, res) => {
92
+ res.redirect('/console');
93
+ });
94
+ app.use((req, res) => {
95
+ res.status(404).json({ success: false, error: 'Not found', path: req.path });
96
+ });
97
+ return new Promise((resolve) => {
98
+ const server = http.createServer(app);
99
+ server.on('error', (error) => {
100
+ try {
101
+ stopWatcher();
102
+ }
103
+ catch { }
104
+ if (error.code === 'EADDRINUSE') {
105
+ resolve({ kind: 'port_conflict', port });
106
+ }
107
+ else {
108
+ resolve({ kind: 'io_error', message: error.message });
109
+ }
110
+ });
111
+ server.listen(port, '127.0.0.1', () => {
112
+ const addr = server.address();
113
+ const actualPort = (addr && typeof addr === 'object') ? addr.port : port;
114
+ const lockDir = path.dirname(lockFilePath);
115
+ void fs.mkdir(lockDir, { recursive: true })
116
+ .then(() => fs.writeFile(lockFilePath, JSON.stringify({ pid: process.pid, port: actualPort }), 'utf-8'))
117
+ .catch((writeErr) => {
118
+ console.warn('[StandaloneConsole] Could not write lock file:', writeErr instanceof Error ? writeErr.message : String(writeErr));
119
+ });
120
+ let stopped = false;
121
+ const stop = () => {
122
+ if (stopped)
123
+ return Promise.resolve();
124
+ stopped = true;
125
+ return new Promise((res) => {
126
+ try {
127
+ stopWatcher();
128
+ }
129
+ catch { }
130
+ const safetyTimer = setTimeout(() => res(), 5000);
131
+ server.close(() => {
132
+ clearTimeout(safetyTimer);
133
+ void fs.unlink(lockFilePath)
134
+ .catch(() => { })
135
+ .finally(() => res());
136
+ });
137
+ });
138
+ };
139
+ resolve({ kind: 'ok', port: actualPort, stop });
140
+ });
141
+ });
142
+ }