@exaudeus/workrail 3.16.0 → 3.17.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/application/use-cases/raw-workflow-file-scanner.js +10 -13
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +72 -0
- package/dist/cli.js +13 -1
- package/dist/config/config-file.d.ts +8 -0
- package/dist/config/config-file.js +141 -0
- package/dist/config/feature-flags.js +8 -0
- package/dist/console/assets/index-BwJelCXK.js +28 -0
- package/dist/console/index.html +1 -1
- package/dist/di/container.d.ts +1 -0
- package/dist/di/container.js +24 -7
- package/dist/infrastructure/session/HttpServer.d.ts +0 -1
- package/dist/infrastructure/session/HttpServer.js +4 -46
- package/dist/manifest.json +101 -109
- package/dist/mcp/assert-output.js +2 -1
- package/dist/mcp/dev-mode.d.ts +1 -0
- package/dist/mcp/dev-mode.js +12 -0
- package/dist/mcp/handler-factory.d.ts +1 -1
- package/dist/mcp/handler-factory.js +8 -7
- package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +1 -0
- package/dist/mcp/handlers/shared/request-workflow-reader.js +90 -20
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +3 -1
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +2 -1
- package/dist/mcp/handlers/v2-execution/index.js +2 -0
- package/dist/mcp/handlers/v2-execution/replay.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/replay.js +3 -0
- package/dist/mcp/handlers/v2-execution/start.js +48 -20
- package/dist/mcp/handlers/v2-workflow.js +4 -2
- package/dist/mcp/output-schemas.d.ts +5 -0
- package/dist/mcp/output-schemas.js +2 -0
- package/dist/mcp/server.js +3 -2
- package/dist/mcp/v2-response-formatter.d.ts +1 -1
- package/dist/mcp/v2-response-formatter.js +2 -3
- package/dist/types/workflow-definition.d.ts +3 -1
- package/dist/types/workflow-definition.js +2 -0
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +1 -2
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +4 -3
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +2 -0
- package/dist/v2/infra/local/pinned-workflow-store/index.js +49 -0
- package/dist/v2/infra/local/remembered-roots-store/index.d.ts +3 -1
- package/dist/v2/infra/local/remembered-roots-store/index.js +6 -3
- package/dist/v2/infra/local/workspace-anchor/index.js +4 -2
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +2 -0
- package/dist/v2/usecases/console-routes.js +3 -2
- package/package.json +1 -1
- package/dist/console/assets/index-BE5PAgPO.js +0 -28
- package/dist/env-flags.d.ts +0 -1
- package/dist/env-flags.js +0 -4
- package/dist/mcp/handlers/v2-resolve-refs-envelope.d.ts +0 -5
- package/dist/mcp/handlers/v2-resolve-refs-envelope.js +0 -17
|
@@ -6,26 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.findWorkflowJsonFiles = findWorkflowJsonFiles;
|
|
7
7
|
exports.scanRawWorkflowFiles = scanRawWorkflowFiles;
|
|
8
8
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
-
const fs_1 = require("fs");
|
|
10
9
|
const path_1 = __importDefault(require("path"));
|
|
11
10
|
async function findWorkflowJsonFiles(baseDirReal) {
|
|
12
11
|
const files = [];
|
|
13
12
|
async function scan(currentDir) {
|
|
14
13
|
const entries = await promises_1.default.readdir(currentDir, { withFileTypes: true });
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
await scan(fullPath);
|
|
22
|
-
}
|
|
23
|
-
else if (entry.isFile() && entry.name.endsWith('.json')) {
|
|
24
|
-
files.push(fullPath);
|
|
25
|
-
}
|
|
14
|
+
const jsonFiles = entries.filter((e) => e.isFile() && e.name.endsWith('.json'));
|
|
15
|
+
const subDirs = entries.filter((e) => e.isDirectory() && e.name !== 'examples');
|
|
16
|
+
for (const f of jsonFiles) {
|
|
17
|
+
files.push(path_1.default.join(currentDir, f.name));
|
|
26
18
|
}
|
|
19
|
+
await Promise.all(subDirs.map((d) => scan(path_1.default.join(currentDir, d.name)).catch((err) => {
|
|
20
|
+
if (err.code !== 'ENOENT')
|
|
21
|
+
throw err;
|
|
22
|
+
})));
|
|
27
23
|
}
|
|
28
24
|
await scan(baseDirReal);
|
|
25
|
+
files.sort();
|
|
29
26
|
return files;
|
|
30
27
|
}
|
|
31
28
|
async function scanRawWorkflowFiles(baseDirReal) {
|
|
@@ -34,7 +31,7 @@ async function scanRawWorkflowFiles(baseDirReal) {
|
|
|
34
31
|
for (const filePath of allJsonFiles) {
|
|
35
32
|
const relativeFilePath = path_1.default.relative(baseDirReal, filePath);
|
|
36
33
|
try {
|
|
37
|
-
const stats =
|
|
34
|
+
const stats = await promises_1.default.stat(filePath);
|
|
38
35
|
if (stats.size > 1000000) {
|
|
39
36
|
results.push({
|
|
40
37
|
kind: 'unparseable',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { executeInitCommand, type InitCommandDeps } from './init.js';
|
|
1
|
+
export { executeInitCommand, executeInitConfigCommand, type InitCommandDeps, type InitConfigCommandDeps } from './init.js';
|
|
2
2
|
export { executeSourcesCommand, getWorkflowSources, type SourcesCommandDeps, type WorkflowSource } from './sources.js';
|
|
3
3
|
export { executeListCommand, type ListCommandDeps, type ListCommandOptions } from './list.js';
|
|
4
4
|
export { executeValidateCommand, type ValidateCommandDeps } from './validate.js';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.detectWorkflowVersion = exports.migrateWorkflowFile = exports.migrateWorkflow = exports.executeMigrateCommand = exports.executeCleanupCommand = exports.executeStartCommand = exports.executeValidateCommand = exports.executeListCommand = exports.getWorkflowSources = exports.executeSourcesCommand = exports.executeInitCommand = void 0;
|
|
3
|
+
exports.detectWorkflowVersion = exports.migrateWorkflowFile = exports.migrateWorkflow = exports.executeMigrateCommand = exports.executeCleanupCommand = exports.executeStartCommand = exports.executeValidateCommand = exports.executeListCommand = exports.getWorkflowSources = exports.executeSourcesCommand = exports.executeInitConfigCommand = exports.executeInitCommand = void 0;
|
|
4
4
|
var init_js_1 = require("./init.js");
|
|
5
5
|
Object.defineProperty(exports, "executeInitCommand", { enumerable: true, get: function () { return init_js_1.executeInitCommand; } });
|
|
6
|
+
Object.defineProperty(exports, "executeInitConfigCommand", { enumerable: true, get: function () { return init_js_1.executeInitConfigCommand; } });
|
|
6
7
|
var sources_js_1 = require("./sources.js");
|
|
7
8
|
Object.defineProperty(exports, "executeSourcesCommand", { enumerable: true, get: function () { return sources_js_1.executeSourcesCommand; } });
|
|
8
9
|
Object.defineProperty(exports, "getWorkflowSources", { enumerable: true, get: function () { return sources_js_1.getWorkflowSources; } });
|
|
@@ -8,4 +8,14 @@ export interface InitCommandDeps {
|
|
|
8
8
|
readonly homedir: () => string;
|
|
9
9
|
readonly joinPath: (...paths: string[]) => string;
|
|
10
10
|
}
|
|
11
|
+
export interface InitConfigCommandDeps {
|
|
12
|
+
readonly mkdir: (path: string, options: {
|
|
13
|
+
recursive: boolean;
|
|
14
|
+
}) => Promise<string | undefined>;
|
|
15
|
+
readonly readFile: (path: string) => Promise<string>;
|
|
16
|
+
readonly writeFile: (path: string, content: string) => Promise<void>;
|
|
17
|
+
readonly homedir: () => string;
|
|
18
|
+
readonly joinPath: (...paths: string[]) => string;
|
|
19
|
+
}
|
|
11
20
|
export declare function executeInitCommand(deps: InitCommandDeps): Promise<CliResult>;
|
|
21
|
+
export declare function executeInitConfigCommand(deps: InitConfigCommandDeps): Promise<CliResult>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.executeInitCommand = executeInitCommand;
|
|
4
|
+
exports.executeInitConfigCommand = executeInitConfigCommand;
|
|
4
5
|
const cli_result_js_1 = require("../types/cli-result.js");
|
|
5
6
|
const SAMPLE_WORKFLOW = {
|
|
6
7
|
id: 'my-custom-workflow',
|
|
@@ -47,3 +48,74 @@ async function executeInitCommand(deps) {
|
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
}
|
|
51
|
+
const CONFIG_FILE_TEMPLATE = `{
|
|
52
|
+
"_comment": "WorkRail configuration file. Uncomment any key to override its default.",
|
|
53
|
+
"_docs": "Full reference: https://github.com/exaudeus/workrail/blob/main/docs/configuration.md",
|
|
54
|
+
|
|
55
|
+
"CACHE_TTL": "300000",
|
|
56
|
+
"WORKRAIL_WORKFLOWS_DIR": "",
|
|
57
|
+
"WORKRAIL_DISABLE_UNIFIED_DASHBOARD": "0",
|
|
58
|
+
"WORKRAIL_DISABLE_AUTO_OPEN": "0",
|
|
59
|
+
"WORKRAIL_DASHBOARD_PORT": "3456",
|
|
60
|
+
|
|
61
|
+
"WORKRAIL_ENABLE_SESSION_TOOLS": "true",
|
|
62
|
+
"WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS": "false",
|
|
63
|
+
"WORKRAIL_VERBOSE_LOGGING": "false",
|
|
64
|
+
"WORKRAIL_ENABLE_AGENTIC_ROUTINES": "true",
|
|
65
|
+
"WORKRAIL_ENABLE_LEAN_WORKFLOWS": "false",
|
|
66
|
+
"WORKRAIL_AUTHORITATIVE_DESCRIPTIONS": "false",
|
|
67
|
+
"WORKRAIL_ENABLE_V2_TOOLS": "true",
|
|
68
|
+
"WORKRAIL_CLEAN_RESPONSE_FORMAT": "false",
|
|
69
|
+
|
|
70
|
+
"WORKFLOW_STORAGE_PATH": "",
|
|
71
|
+
"WORKFLOW_GIT_REPOS": "",
|
|
72
|
+
"WORKFLOW_GIT_REPO_URL": "",
|
|
73
|
+
"WORKFLOW_GIT_REPO_BRANCH": "main",
|
|
74
|
+
"WORKFLOW_GIT_SYNC_INTERVAL": "60",
|
|
75
|
+
|
|
76
|
+
"WORKRAIL_LOG_LEVEL": "SILENT",
|
|
77
|
+
"WORKRAIL_LOG_FORMAT": "human",
|
|
78
|
+
"WORKRAIL_DATA_DIR": "",
|
|
79
|
+
"WORKRAIL_CACHE_DIR": "",
|
|
80
|
+
|
|
81
|
+
"WORKRAIL_JSON_RESPONSES": "false"
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
async function executeInitConfigCommand(deps) {
|
|
85
|
+
const configDir = deps.joinPath(deps.homedir(), '.workrail');
|
|
86
|
+
const configPath = deps.joinPath(configDir, 'config.json');
|
|
87
|
+
try {
|
|
88
|
+
const existing = await deps.readFile(configPath);
|
|
89
|
+
return (0, cli_result_js_1.success)({
|
|
90
|
+
message: `Config file already exists at ${configPath}`,
|
|
91
|
+
details: [
|
|
92
|
+
'Current contents:',
|
|
93
|
+
existing,
|
|
94
|
+
'(File was not modified. Delete it and re-run to regenerate the template.)',
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
await deps.mkdir(configDir, { recursive: true });
|
|
102
|
+
await deps.writeFile(configPath, CONFIG_FILE_TEMPLATE);
|
|
103
|
+
return (0, cli_result_js_1.success)({
|
|
104
|
+
message: `Config file written to ${configPath}`,
|
|
105
|
+
details: [
|
|
106
|
+
'Edit the file to set your preferred defaults.',
|
|
107
|
+
'Environment variables always override values in this file.',
|
|
108
|
+
'Sensitive values (tokens, keys) must still be set as environment variables.',
|
|
109
|
+
],
|
|
110
|
+
suggestions: [
|
|
111
|
+
`Edit: ${configPath}`,
|
|
112
|
+
'Documentation: workrail docs configuration',
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return (0, cli_result_js_1.failure)(`Failed to write config file: ${error instanceof Error ? error.message : String(error)}`, {
|
|
118
|
+
suggestions: ['Check that you have write permissions to your home directory'],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,19 @@ program
|
|
|
26
26
|
program
|
|
27
27
|
.command('init')
|
|
28
28
|
.description('Initialize user workflow directory with sample workflows')
|
|
29
|
-
.
|
|
29
|
+
.option('--config', 'Write a ~/.workrail/config.json template instead of initializing workflows')
|
|
30
|
+
.action(async (options) => {
|
|
31
|
+
if (options.config) {
|
|
32
|
+
const result = await (0, index_js_1.executeInitConfigCommand)({
|
|
33
|
+
mkdir: (p, opts) => fs_1.default.promises.mkdir(p, opts),
|
|
34
|
+
readFile: (p) => fs_1.default.promises.readFile(p, 'utf-8'),
|
|
35
|
+
writeFile: (p, content) => fs_1.default.promises.writeFile(p, content, 'utf-8'),
|
|
36
|
+
homedir: os_1.default.homedir,
|
|
37
|
+
joinPath: path_1.default.join,
|
|
38
|
+
});
|
|
39
|
+
(0, interpret_result_js_1.interpretCliResultWithoutDI)(result);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
30
42
|
const result = await (0, index_js_1.executeInitCommand)({
|
|
31
43
|
mkdir: (p, opts) => fs_1.default.promises.mkdir(p, opts),
|
|
32
44
|
readdir: (p) => fs_1.default.promises.readdir(p),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Result } from '../runtime/result.js';
|
|
2
|
+
export type ConfigFileError = {
|
|
3
|
+
readonly _tag: 'ConfigFileError';
|
|
4
|
+
readonly message: string;
|
|
5
|
+
readonly cause?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare function ensureWorkrailConfigFile(): void;
|
|
8
|
+
export declare function loadWorkrailConfigFile(): Result<Record<string, string>, ConfigFileError>;
|
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ensureWorkrailConfigFile = ensureWorkrailConfigFile;
|
|
37
|
+
exports.loadWorkrailConfigFile = loadWorkrailConfigFile;
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const zod_1 = require("zod");
|
|
42
|
+
const result_js_1 = require("../runtime/result.js");
|
|
43
|
+
const ALLOWED_CONFIG_FILE_KEYS = new Set([
|
|
44
|
+
'CACHE_TTL',
|
|
45
|
+
'WORKRAIL_WORKFLOWS_DIR',
|
|
46
|
+
'WORKRAIL_DISABLE_UNIFIED_DASHBOARD',
|
|
47
|
+
'WORKRAIL_DISABLE_AUTO_OPEN',
|
|
48
|
+
'WORKRAIL_DASHBOARD_PORT',
|
|
49
|
+
'WORKRAIL_DEV',
|
|
50
|
+
'WORKRAIL_ENABLE_SESSION_TOOLS',
|
|
51
|
+
'WORKRAIL_ENABLE_EXPERIMENTAL_WORKFLOWS',
|
|
52
|
+
'WORKRAIL_VERBOSE_LOGGING',
|
|
53
|
+
'WORKRAIL_ENABLE_AGENTIC_ROUTINES',
|
|
54
|
+
'WORKRAIL_ENABLE_LEAN_WORKFLOWS',
|
|
55
|
+
'WORKRAIL_AUTHORITATIVE_DESCRIPTIONS',
|
|
56
|
+
'WORKRAIL_ENABLE_V2_TOOLS',
|
|
57
|
+
'WORKRAIL_CLEAN_RESPONSE_FORMAT',
|
|
58
|
+
'WORKFLOW_STORAGE_PATH',
|
|
59
|
+
'WORKFLOW_GIT_REPOS',
|
|
60
|
+
'WORKFLOW_GIT_REPO_URL',
|
|
61
|
+
'WORKFLOW_GIT_REPO_BRANCH',
|
|
62
|
+
'WORKFLOW_GIT_SYNC_INTERVAL',
|
|
63
|
+
'WORKRAIL_LOG_LEVEL',
|
|
64
|
+
'WORKRAIL_LOG_FORMAT',
|
|
65
|
+
'WORKRAIL_DATA_DIR',
|
|
66
|
+
'WORKRAIL_CACHE_DIR',
|
|
67
|
+
'WORKRAIL_JSON_RESPONSES',
|
|
68
|
+
]);
|
|
69
|
+
const ConfigFileSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.string());
|
|
70
|
+
const CONFIG_FILE_TEMPLATE = `{
|
|
71
|
+
"_comment": "WorkRail configuration. Values here are defaults; process.env always wins.",
|
|
72
|
+
"_docs": "https://github.com/exaudeus/workrail/blob/main/docs/configuration.md",
|
|
73
|
+
|
|
74
|
+
"CACHE_TTL": "300000",
|
|
75
|
+
"WORKRAIL_ENABLE_SESSION_TOOLS": "true",
|
|
76
|
+
"WORKRAIL_ENABLE_AGENTIC_ROUTINES": "true",
|
|
77
|
+
"WORKRAIL_ENABLE_V2_TOOLS": "true",
|
|
78
|
+
"WORKRAIL_ENABLE_LEAN_WORKFLOWS": "false",
|
|
79
|
+
"WORKRAIL_AUTHORITATIVE_DESCRIPTIONS": "false",
|
|
80
|
+
"WORKRAIL_CLEAN_RESPONSE_FORMAT": "false",
|
|
81
|
+
"WORKRAIL_VERBOSE_LOGGING": "false",
|
|
82
|
+
|
|
83
|
+
"WORKFLOW_STORAGE_PATH": "",
|
|
84
|
+
"WORKFLOW_GIT_REPOS": "",
|
|
85
|
+
|
|
86
|
+
"WORKRAIL_LOG_LEVEL": "SILENT",
|
|
87
|
+
"WORKRAIL_LOG_FORMAT": "human"
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
90
|
+
function ensureWorkrailConfigFile() {
|
|
91
|
+
if (process.env['VITEST'])
|
|
92
|
+
return;
|
|
93
|
+
const configPath = path.join(os.homedir(), '.workrail', 'config.json');
|
|
94
|
+
try {
|
|
95
|
+
fs.accessSync(configPath);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
try {
|
|
99
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
100
|
+
fs.writeFileSync(configPath, CONFIG_FILE_TEMPLATE, 'utf-8');
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function loadWorkrailConfigFile() {
|
|
107
|
+
const configPath = path.join(os.homedir(), '.workrail', 'config.json');
|
|
108
|
+
let rawContent;
|
|
109
|
+
try {
|
|
110
|
+
rawContent = fs.readFileSync(configPath, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
const code = e.code;
|
|
114
|
+
if (code !== 'ENOENT') {
|
|
115
|
+
console.warn(`[WorkRail] Could not read config file at ${configPath}: ${e.message}`);
|
|
116
|
+
}
|
|
117
|
+
return (0, result_js_1.ok)({});
|
|
118
|
+
}
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = JSON.parse(rawContent);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
console.warn(`[WorkRail] config file at ${configPath} contains invalid JSON -- ignoring it. Fix or regenerate with "workrail init --config".`);
|
|
125
|
+
return (0, result_js_1.ok)({});
|
|
126
|
+
}
|
|
127
|
+
const result = ConfigFileSchema.safeParse(parsed);
|
|
128
|
+
if (!result.success) {
|
|
129
|
+
console.warn(`[WorkRail] config file at ${configPath} has an unexpected shape -- ignoring it. Expected a flat JSON object with string values.`);
|
|
130
|
+
return (0, result_js_1.ok)({});
|
|
131
|
+
}
|
|
132
|
+
const validated = {};
|
|
133
|
+
for (const [key, value] of Object.entries(result.data)) {
|
|
134
|
+
if (!ALLOWED_CONFIG_FILE_KEYS.has(key)) {
|
|
135
|
+
console.warn(`[WorkRail] config file: unknown key "${key}" -- ignored. See "workrail init --config" for supported keys.`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
validated[key] = value;
|
|
139
|
+
}
|
|
140
|
+
return (0, result_js_1.ok)(validated);
|
|
141
|
+
}
|
|
@@ -77,6 +77,14 @@ exports.FEATURE_FLAG_DEFINITIONS = [
|
|
|
77
77
|
since: '0.11.0',
|
|
78
78
|
stable: false,
|
|
79
79
|
},
|
|
80
|
+
{
|
|
81
|
+
key: 'devMode',
|
|
82
|
+
envVar: 'WORKRAIL_DEV',
|
|
83
|
+
defaultValue: false,
|
|
84
|
+
description: 'Enable development features: staleness visibility for all workflow categories, structured tool-call timing on stderr, and /api/v2/perf/tool-calls endpoint',
|
|
85
|
+
since: '0.11.0',
|
|
86
|
+
stable: false,
|
|
87
|
+
},
|
|
80
88
|
];
|
|
81
89
|
function parseBoolean(value, defaultValue) {
|
|
82
90
|
if (value === undefined) {
|