@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.
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +3 -1
- package/dist/cli/commands/worktrain-await.js +11 -9
- package/dist/cli/commands/worktrain-daemon-install.d.ts +35 -0
- package/dist/cli/commands/worktrain-daemon-install.js +291 -0
- package/dist/cli/commands/worktrain-daemon.d.ts +31 -0
- package/dist/cli/commands/worktrain-daemon.js +272 -0
- package/dist/cli/commands/worktrain-spawn.js +11 -9
- package/dist/cli-worktrain.js +329 -0
- package/dist/cli.js +4 -22
- package/dist/console/standalone-console.d.ts +28 -0
- package/dist/console/standalone-console.js +142 -0
- package/dist/{console/assets/index-6H9DeFxj.js → console-ui/assets/index-BuJFLLfY.js} +1 -1
- package/dist/{console → console-ui}/index.html +1 -1
- package/dist/daemon/agent-loop.d.ts +26 -0
- package/dist/daemon/agent-loop.js +53 -2
- package/dist/daemon/daemon-events.d.ts +103 -0
- package/dist/daemon/daemon-events.js +56 -0
- package/dist/daemon/workflow-runner.d.ts +6 -3
- package/dist/daemon/workflow-runner.js +229 -33
- package/dist/infrastructure/session/HttpServer.js +133 -34
- package/dist/manifest.json +134 -70
- package/dist/mcp/output-schemas.d.ts +30 -30
- package/dist/mcp/transports/bridge-events.d.ts +4 -0
- package/dist/mcp/transports/fatal-exit.js +4 -0
- package/dist/mcp/transports/http-entry.js +2 -0
- package/dist/mcp/transports/stdio-entry.js +26 -6
- package/dist/mcp/v2/tools.d.ts +4 -4
- package/dist/trigger/adapters/github-poller.d.ts +44 -0
- package/dist/trigger/adapters/github-poller.js +190 -0
- package/dist/trigger/adapters/gitlab-poller.d.ts +27 -0
- package/dist/trigger/adapters/gitlab-poller.js +81 -0
- package/dist/trigger/delivery-client.d.ts +2 -1
- package/dist/trigger/delivery-client.js +4 -1
- package/dist/trigger/index.d.ts +4 -1
- package/dist/trigger/index.js +5 -1
- package/dist/trigger/polled-event-store.d.ts +22 -0
- package/dist/trigger/polled-event-store.js +173 -0
- package/dist/trigger/polling-scheduler.d.ts +20 -0
- package/dist/trigger/polling-scheduler.js +249 -0
- package/dist/trigger/trigger-listener.d.ts +5 -0
- package/dist/trigger/trigger-listener.js +53 -4
- package/dist/trigger/trigger-router.d.ts +4 -2
- package/dist/trigger/trigger-router.js +7 -4
- package/dist/trigger/trigger-store.js +114 -33
- package/dist/trigger/types.d.ts +17 -1
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +224 -224
- package/dist/v2/durable-core/schemas/session/events.d.ts +42 -42
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +6 -6
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +2 -2
- package/dist/v2/durable-core/tokens/payloads.d.ts +52 -52
- package/dist/v2/usecases/console-routes.js +3 -3
- package/dist/v2/usecases/console-service.js +133 -9
- package/dist/v2/usecases/console-types.d.ts +7 -0
- package/docs/design/daemon-conversation-logging-plan.md +98 -0
- package/docs/design/daemon-conversation-logging-review.md +55 -0
- package/docs/design/daemon-conversation-logging.md +129 -0
- package/docs/design/github-polling-adapter-design-candidates.md +226 -0
- package/docs/design/github-polling-adapter-design-review-findings.md +131 -0
- package/docs/design/github-polling-adapter-implementation-plan.md +284 -0
- package/docs/design/implementation_plan.md +192 -0
- package/docs/design/workflow-id-validation-at-startup.md +146 -0
- package/docs/design/workflow-id-validation-design-review.md +87 -0
- package/docs/design/workflow-id-validation-implementation-plan.md +185 -0
- package/docs/design/worktrain-system-prompt-report-issue-candidates.md +135 -0
- package/docs/design/worktrain-system-prompt-report-issue-design-review.md +73 -0
- package/docs/ideas/backlog.md +465 -0
- package/package.json +1 -1
- package/workflows/architecture-scalability-audit.json +1 -1
- package/workflows/bug-investigation.agentic.v2.json +3 -3
- package/workflows/coding-task-workflow-agentic.json +32 -32
- package/workflows/coding-task-workflow-agentic.lean.v2.json +1 -1
- package/workflows/coding-task-workflow-agentic.v2.json +7 -7
- package/workflows/mr-review-workflow.agentic.v2.json +21 -12
- package/workflows/personal-learning-materials-creation-branched.json +2 -2
- package/workflows/production-readiness-audit.json +1 -1
- package/workflows/relocation-workflow-us.json +2 -2
- package/workflows/ui-ux-design-workflow.json +14 -14
- package/workflows/workflow-for-workflows.json +3 -3
- package/workflows/workflow-for-workflows.v2.json +2 -2
- package/workflows/wr.discovery.json +1 -1
- /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 {
|
|
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
|
-
|
|
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
|
+
}
|