@potential-guide/pguide-task-engine 0.0.0-stage → 0.1.0-rc.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/LICENSE +21 -0
- package/README.md +74 -2
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +225 -0
- package/dist/config.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +89 -0
- package/dist/main.js.map +1 -0
- package/dist/service.d.ts +12 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +106 -0
- package/dist/service.js.map +1 -0
- package/package.json +45 -3
- package/settings.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shazhou-ww
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,75 @@
|
|
|
1
|
-
#
|
|
1
|
+
# pguide task-engine
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Install `@potential-guide/pguide-task-engine` beside `pguide`, with its
|
|
4
|
+
`pguide-task-engine` executable on PATH (or in pguide commandDirectories).
|
|
5
|
+
It implements the existing `pguide-command-v1` discovery protocol. No automatic
|
|
6
|
+
settings registration or user configuration writes occur.
|
|
7
|
+
|
|
8
|
+
```powershell
|
|
9
|
+
pguide task-engine --no-global-config --port 0 --database .\new-tasks.sqlite --ipfs-gateway-url http://127.0.0.1:8080
|
|
10
|
+
pguide-task-engine --config .\server.yaml --ui
|
|
11
|
+
pguide task-engine --help --format json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Provide an explicit read-only Trustless Gateway URL through CLI, the specified
|
|
15
|
+
YAML/JSON file or `task-engine.ipfsGatewayUrl` in user settings. There is no default
|
|
16
|
+
node or public Gateway, RPC selection or fallback. Author publishing/pinning is unchanged.
|
|
17
|
+
**Breaking change:** remove `ipfsRpcUrl` / `ipfsTransport`, their `task-engine.`
|
|
18
|
+
setting IDs and old flags; use `--ipfs-gateway-url` instead. Old fields fail even
|
|
19
|
+
when overridden. User files are never automatically rewritten.
|
|
20
|
+
`--help` prints the actual platform-specific pguide user configuration path,
|
|
21
|
+
defaults, all options and boundary rules without opening a DB, listener or Gateway
|
|
22
|
+
connection. See [the configuration guide](../../docs/task-server.md).
|
|
23
|
+
|
|
24
|
+
The package depends on the public Web UI application package, including its
|
|
25
|
+
server runtime and browser assets; no source-checkout/private-app dependency is
|
|
26
|
+
required. Without `--ui` no UI listener is started. Engine/UI communicate through
|
|
27
|
+
public HTTP, not an Engine object or SQLite access.
|
|
28
|
+
|
|
29
|
+
The package-owned `objectives.yaml` permits `@potential-guide/task-sdk` only for
|
|
30
|
+
the existing development dependency that authors standard Bundle fixtures in
|
|
31
|
+
service tests, following the Web UI application's declaration. It is not a
|
|
32
|
+
production dependency or a service runtime import; no repository-wide dependency
|
|
33
|
+
exception is required.
|
|
34
|
+
|
|
35
|
+
## Real local Kubo end-to-end verification
|
|
36
|
+
|
|
37
|
+
The opt-in integration test uses the repository's actual `pguide` discovery and
|
|
38
|
+
command executables, not a mock IPFS client or an npm tarball. From the repository
|
|
39
|
+
root, after installing dependencies:
|
|
40
|
+
|
|
41
|
+
```powershell
|
|
42
|
+
pnpm exec turbo run build --filter=@potential-guide/pguide-task-engine... --filter=@potential-guide/pguide-task-bundle... --filter=pguide...
|
|
43
|
+
$env:PGUIDE_E2E_KUBO_RPC = 'http://127.0.0.1:5001'
|
|
44
|
+
$env:PGUIDE_E2E_KUBO_GATEWAY = 'http://127.0.0.1:8080'
|
|
45
|
+
pnpm exec tsx --test apps\pguide-task-engine\test\kubo.e2e.test.ts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Both URLs must be explicitly supplied; without them the test is skipped. Use an
|
|
49
|
+
already running, caller-managed Kubo whose RPC permits CAR imports and whose
|
|
50
|
+
Gateway serves raw blocks. The test never starts/stops Kubo or edits its
|
|
51
|
+
configuration. It imports and **recursively pins** its generated CAR with
|
|
52
|
+
`POST /api/v0/dag/import?pin-roots=true`; imported roots remain pinned afterward,
|
|
53
|
+
including roots imported before a later assertion fails. It never removes pins
|
|
54
|
+
from the shared node. Only run it when these writes are authorized.
|
|
55
|
+
|
|
56
|
+
The test initializes a separate author package, reuses the repository's installed
|
|
57
|
+
SDK/TypeBox dependencies, builds and checks the CAR, imports it into real Kubo,
|
|
58
|
+
and runs a CLI-owned Engine against the Gateway. It verifies streamed Bundle
|
|
59
|
+
resource reads, a business-created JSON file, the completed Task/Run result,
|
|
60
|
+
`run.started`, `run.dispatched`, `run.progress`, `run.outcome`, `run.exited`,
|
|
61
|
+
`run.reclaimed` history and diagnostic logs. Restarting with the same SQLite DB
|
|
62
|
+
must preserve the result/history/logs and return the same Task for a repeated
|
|
63
|
+
Request. An outcome report is not itself a terminal Task: completion is checked
|
|
64
|
+
after physical Worker exit and reclamation.
|
|
65
|
+
|
|
66
|
+
Each Engine uses a private DB and a random loopback port. Ready diagnostics
|
|
67
|
+
include its URL and PID. A test launcher records the owned service PID before
|
|
68
|
+
startup, so even a readiness timeout can terminate the actual service rather
|
|
69
|
+
than just the dispatching CLI. All owned CLI processes and temporary author/DB files
|
|
70
|
+
are cleaned up; the shared Kubo remains running. Windows process termination is
|
|
71
|
+
forced, so the test waits for Worker reclamation before stopping its Engine.
|
|
72
|
+
It does not claim to verify graceful Windows OS signal delivery.
|
|
73
|
+
Optionally set `PGUIDE_E2E_REPORT` to an absolute, writable JSON filename to retain
|
|
74
|
+
the CID, Request/Task/Run IDs, endpoints/PIDs, observed events/logs and exact
|
|
75
|
+
business artifact content after temporary files and services have been removed.
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ServiceConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
database: string;
|
|
5
|
+
ipfsGatewayUrl: string;
|
|
6
|
+
scope: string;
|
|
7
|
+
ui: boolean;
|
|
8
|
+
uiOptions: {
|
|
9
|
+
host: string;
|
|
10
|
+
port: number;
|
|
11
|
+
favoritesFile: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare class ConfigurationError extends Error {
|
|
15
|
+
}
|
|
16
|
+
/** Validate every provided value before replacing complete settings across layers. */
|
|
17
|
+
export declare function validateLayer(value: unknown, base: string, source: string): Partial<ServiceConfig>;
|
|
18
|
+
export declare function parseArguments(argv: readonly string[]): {
|
|
19
|
+
options: import("@potential-guide/cli-core").GlobalOptions;
|
|
20
|
+
cli: Record<string, unknown>;
|
|
21
|
+
configFile: string | undefined;
|
|
22
|
+
global: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function resolveConfig(parsed: ReturnType<typeof parseArguments>): Promise<ServiceConfig>;
|
|
25
|
+
export declare function requireGateway(config: Partial<ServiceConfig>): void;
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AACD,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AA2BhD,sFAAsF;AACtF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CA2DxB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE;;;;;EAiDrD;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,GACxC,OAAO,CAAC,aAAa,CAAC,CAoExB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAKnE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, extname, resolve } from "node:path";
|
|
3
|
+
import { extractGlobals, loadConfig, parseConfig, parseJsonc, userConfigPath, } from "@potential-guide/cli-core";
|
|
4
|
+
import { parseDocument } from "yaml";
|
|
5
|
+
export class ConfigurationError extends Error {
|
|
6
|
+
}
|
|
7
|
+
const fields = new Set(["host", "port", "database", "ipfsGatewayUrl", "scope", "ui", "uiOptions"]);
|
|
8
|
+
const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
function invalid(source, field) {
|
|
10
|
+
// Never include values, parser excerpts or URLs in diagnostics.
|
|
11
|
+
throw new ConfigurationError(`Invalid ${field} in ${source}.`);
|
|
12
|
+
}
|
|
13
|
+
function retired(source) {
|
|
14
|
+
throw new ConfigurationError(`RPC/transport service configuration is retired in ${source}. Remove ipfsRpcUrl/ipfsTransport (including task-engine. setting IDs) and --ipfs-rpc-url/--ipfs-transport; migrate to ipfsGatewayUrl or --ipfs-gateway-url with an explicit read-only Gateway URL.`);
|
|
15
|
+
}
|
|
16
|
+
function host(value, source) {
|
|
17
|
+
if (!["127.0.0.1", "localhost", "::1"].includes(value))
|
|
18
|
+
invalid(source, "host");
|
|
19
|
+
return value === "localhost" ? "127.0.0.1" : value;
|
|
20
|
+
}
|
|
21
|
+
function port(value, source) {
|
|
22
|
+
if (!Number.isInteger(value) || value < 0 || value > 65535)
|
|
23
|
+
invalid(source, "port");
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function path(value, base, source) {
|
|
27
|
+
if (typeof value !== "string" || !value.trim() || value.includes("\0"))
|
|
28
|
+
invalid(source, "path");
|
|
29
|
+
return resolve(base, value);
|
|
30
|
+
}
|
|
31
|
+
/** Validate every provided value before replacing complete settings across layers. */
|
|
32
|
+
export function validateLayer(value, base, source) {
|
|
33
|
+
if (!object(value))
|
|
34
|
+
invalid(source, "configuration");
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
37
|
+
if (key === "ipfsRpcUrl" || key === "ipfsTransport")
|
|
38
|
+
retired(source);
|
|
39
|
+
if (!fields.has(key))
|
|
40
|
+
invalid(source, "unknown service field");
|
|
41
|
+
switch (key) {
|
|
42
|
+
case "host":
|
|
43
|
+
result.host = host(entry, source);
|
|
44
|
+
break;
|
|
45
|
+
case "port":
|
|
46
|
+
result.port = port(entry, source);
|
|
47
|
+
break;
|
|
48
|
+
case "database":
|
|
49
|
+
result.database = path(entry, base, source);
|
|
50
|
+
break;
|
|
51
|
+
case "ipfsGatewayUrl": {
|
|
52
|
+
let url;
|
|
53
|
+
try {
|
|
54
|
+
if (typeof entry !== "string")
|
|
55
|
+
invalid(source, key);
|
|
56
|
+
url = new URL(entry);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
invalid(source, key);
|
|
60
|
+
}
|
|
61
|
+
if (!["http:", "https:"].includes(url.protocol) ||
|
|
62
|
+
url.username ||
|
|
63
|
+
url.password ||
|
|
64
|
+
url.href.includes("?") ||
|
|
65
|
+
url.href.includes("#"))
|
|
66
|
+
invalid(source, key);
|
|
67
|
+
result[key] = url.href;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "scope":
|
|
71
|
+
if (typeof entry !== "string" || !/^[a-zA-Z0-9_-]{1,64}$/.test(entry))
|
|
72
|
+
invalid(source, key);
|
|
73
|
+
result.scope = entry;
|
|
74
|
+
break;
|
|
75
|
+
case "ui":
|
|
76
|
+
if (typeof entry !== "boolean")
|
|
77
|
+
invalid(source, key);
|
|
78
|
+
result.ui = entry;
|
|
79
|
+
break;
|
|
80
|
+
case "uiOptions":
|
|
81
|
+
if (!object(entry) ||
|
|
82
|
+
Object.keys(entry).length !== 3 ||
|
|
83
|
+
!["host", "port", "favoritesFile"].every((name) => Object.hasOwn(entry, name)))
|
|
84
|
+
invalid(source, key);
|
|
85
|
+
result.uiOptions = {
|
|
86
|
+
host: host(entry.host, source),
|
|
87
|
+
port: port(entry.port, source),
|
|
88
|
+
favoritesFile: path(entry.favoritesFile, base, source),
|
|
89
|
+
};
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
export function parseArguments(argv) {
|
|
96
|
+
const { options, rest } = extractGlobals(argv, { serviceConfig: true });
|
|
97
|
+
const cli = {};
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
let configFile;
|
|
100
|
+
let global = true;
|
|
101
|
+
const names = {
|
|
102
|
+
"--host": "host",
|
|
103
|
+
"--port": "port",
|
|
104
|
+
"--database": "database",
|
|
105
|
+
"--ipfs-gateway-url": "ipfsGatewayUrl",
|
|
106
|
+
"--scope": "scope",
|
|
107
|
+
"--ui-options": "uiOptions",
|
|
108
|
+
};
|
|
109
|
+
for (let index = 0; index < rest.length; index++) {
|
|
110
|
+
const raw = rest[index];
|
|
111
|
+
const equals = raw.indexOf("=");
|
|
112
|
+
const flag = equals < 0 ? raw : raw.slice(0, equals);
|
|
113
|
+
if (flag === "--ipfs-rpc-url" || flag === "--ipfs-transport")
|
|
114
|
+
retired("CLI");
|
|
115
|
+
const key = flag === "--no-ui" ? "--ui" : flag;
|
|
116
|
+
if (seen.has(key))
|
|
117
|
+
throw new ConfigurationError("Repeated service option.");
|
|
118
|
+
seen.add(key);
|
|
119
|
+
if (["--ui", "--no-ui", "--no-global-config"].includes(flag)) {
|
|
120
|
+
if (equals >= 0)
|
|
121
|
+
throw new ConfigurationError("Boolean switches do not take values.");
|
|
122
|
+
if (flag === "--no-global-config")
|
|
123
|
+
global = false;
|
|
124
|
+
else
|
|
125
|
+
cli.ui = flag === "--ui";
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (flag !== "--config" && !Object.hasOwn(names, flag))
|
|
129
|
+
throw new ConfigurationError("Unknown service option.");
|
|
130
|
+
const value = equals < 0 ? rest[++index] : raw.slice(equals + 1);
|
|
131
|
+
if (!value || value.startsWith("--"))
|
|
132
|
+
throw new ConfigurationError("Service option requires a value.");
|
|
133
|
+
if (flag === "--config")
|
|
134
|
+
configFile = resolve(options.cwd, value);
|
|
135
|
+
else {
|
|
136
|
+
const field = names[flag];
|
|
137
|
+
if (field === "port") {
|
|
138
|
+
if (!/^\d+$/.test(value))
|
|
139
|
+
invalid("CLI", field);
|
|
140
|
+
cli[field] = Number(value);
|
|
141
|
+
}
|
|
142
|
+
else if (field === "uiOptions") {
|
|
143
|
+
try {
|
|
144
|
+
cli[field] = JSON.parse(value);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
invalid("CLI", field);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else
|
|
151
|
+
cli[field] = value;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { options, cli, configFile, global };
|
|
155
|
+
}
|
|
156
|
+
export async function resolveConfig(parsed) {
|
|
157
|
+
const cwd = parsed.options.cwd;
|
|
158
|
+
const defaults = {
|
|
159
|
+
host: "127.0.0.1",
|
|
160
|
+
port: 3000,
|
|
161
|
+
database: resolve(cwd, "tasks.sqlite"),
|
|
162
|
+
scope: "local",
|
|
163
|
+
ui: false,
|
|
164
|
+
uiOptions: {
|
|
165
|
+
host: "127.0.0.1",
|
|
166
|
+
port: 4310,
|
|
167
|
+
favoritesFile: resolve(cwd, "task-favorites.json"),
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
let user = {};
|
|
171
|
+
if (parsed.global) {
|
|
172
|
+
try {
|
|
173
|
+
const userPath = userConfigPath();
|
|
174
|
+
const text = await readFile(userPath, "utf8").catch((error) => {
|
|
175
|
+
if (error.code === "ENOENT")
|
|
176
|
+
return "{}";
|
|
177
|
+
throw error;
|
|
178
|
+
});
|
|
179
|
+
// Validate explicit service fields before catalog validation: old registrations
|
|
180
|
+
// may omit retired IDs or conflict with the bundled settings description.
|
|
181
|
+
user = validateLayer(Object.fromEntries(Object.entries(parseConfig(text))
|
|
182
|
+
.filter(([id]) => id.startsWith("task-engine."))
|
|
183
|
+
.map(([id, value]) => [id.slice(12), value])), dirname(userPath), "pguide user config");
|
|
184
|
+
await loadConfig(cwd, [], { project: false });
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (error instanceof ConfigurationError)
|
|
188
|
+
throw error;
|
|
189
|
+
throw new ConfigurationError("Cannot read or validate pguide user configuration/settings registry.");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
let file = {};
|
|
193
|
+
if (parsed.configFile) {
|
|
194
|
+
const extension = extname(parsed.configFile).toLowerCase();
|
|
195
|
+
if (![".yaml", ".yml", ".json"].includes(extension))
|
|
196
|
+
throw new ConfigurationError("Service --config requires YAML/JSON data. Executable .mjs configs are retired; migrate to declarative fields.");
|
|
197
|
+
let value;
|
|
198
|
+
try {
|
|
199
|
+
const text = await readFile(parsed.configFile, "utf8");
|
|
200
|
+
if (extension === ".json") {
|
|
201
|
+
value = JSON.parse(text);
|
|
202
|
+
parseJsonc(text);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const document = parseDocument(text, { uniqueKeys: true });
|
|
206
|
+
if (document.errors.length || document.warnings.length)
|
|
207
|
+
invalid("service file", "YAML");
|
|
208
|
+
value = document.toJS({ maxAliasCount: 0 });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
throw new ConfigurationError("Cannot read or parse service YAML/JSON file.");
|
|
213
|
+
}
|
|
214
|
+
file = validateLayer(value, dirname(parsed.configFile), "service file");
|
|
215
|
+
}
|
|
216
|
+
const cli = validateLayer(parsed.cli, cwd, "CLI");
|
|
217
|
+
const final = { ...defaults, ...user, ...file, ...cli };
|
|
218
|
+
requireGateway(final);
|
|
219
|
+
return validateLayer(final, cwd, "effective configuration");
|
|
220
|
+
}
|
|
221
|
+
export function requireGateway(config) {
|
|
222
|
+
if (!config.ipfsGatewayUrl)
|
|
223
|
+
throw new ConfigurationError("Service requires an explicit ipfsGatewayUrl; provide --ipfs-gateway-url or task-engine.ipfsGatewayUrl. No default Gateway is selected.");
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { userConfigPath } from "@potential-guide/cli-core";
|
|
3
|
+
import { ConfigurationError, parseArguments, resolveConfig } from "./config.js";
|
|
4
|
+
const metadata = {
|
|
5
|
+
protocol: "pguide-command-v1",
|
|
6
|
+
command: "task-engine",
|
|
7
|
+
version: "0.1.0-rc.0",
|
|
8
|
+
description: "Start a foreground loopback Task Engine, optionally with its HTTP Web UI.",
|
|
9
|
+
};
|
|
10
|
+
async function main() {
|
|
11
|
+
const argv = process.argv.slice(2);
|
|
12
|
+
if (argv.length === 1 && argv[0] === "--pguide-command-metadata") {
|
|
13
|
+
console.log(JSON.stringify(metadata));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const parsed = parseArguments(argv.map((arg) => (arg === "-h" ? "--help" : arg)));
|
|
17
|
+
if (parsed.options.help) {
|
|
18
|
+
const help = {
|
|
19
|
+
schemaVersion: 1,
|
|
20
|
+
command: "task-engine",
|
|
21
|
+
usage: "pguide task-engine [--config server.yaml|server.json] [options]",
|
|
22
|
+
options: [
|
|
23
|
+
"--host <127.0.0.1|localhost|::1>",
|
|
24
|
+
"--port <0..65535>",
|
|
25
|
+
"--database <path>",
|
|
26
|
+
"--ipfs-gateway-url <HTTP(S) Gateway base URL; required from an enabled source>",
|
|
27
|
+
"--scope <local-scope>",
|
|
28
|
+
"--ui",
|
|
29
|
+
"--no-ui",
|
|
30
|
+
'--ui-options \'{"host":"127.0.0.1","port":4310,"favoritesFile":"favorites.json"}\'',
|
|
31
|
+
"--no-global-config",
|
|
32
|
+
"--cwd <directory>",
|
|
33
|
+
"--help",
|
|
34
|
+
"--format json",
|
|
35
|
+
],
|
|
36
|
+
precedence: "Explicit CLI > explicit YAML/JSON file > pguide USER config.jsonc > defaults. Project service settings are never read.",
|
|
37
|
+
globalConfig: userConfigPath(),
|
|
38
|
+
paths: "Effective CWD is --cwd or process CWD for both entrypoints and --config. Each file's paths are relative to that file; CLI paths are relative to effective CWD.",
|
|
39
|
+
validation: "Every provided layer is validated even when overridden. Complete settings (including uiOptions) replace, never deep merge. No executable config or environment service overrides.",
|
|
40
|
+
isolation: "--no-global-config skips the user main file, including top-level discovery and user commandDirectories. PATH and project discovery remain available.",
|
|
41
|
+
defaults: {
|
|
42
|
+
host: "127.0.0.1",
|
|
43
|
+
port: 3000,
|
|
44
|
+
database: "tasks.sqlite",
|
|
45
|
+
scope: "local",
|
|
46
|
+
ui: false,
|
|
47
|
+
uiOptions: { host: "127.0.0.1", port: 4310, favoritesFile: "task-favorites.json" },
|
|
48
|
+
},
|
|
49
|
+
security: "No token; fixed loopback only (localhost becomes 127.0.0.1; ::1 supported). Caller local-cli is limited to the configured scope. Host/Origin/fetch-site, GET/POST and JSON writes are checked. Do not expose through a proxy. Other local users/processes are not isolated.",
|
|
50
|
+
lifecycle: "Foreground only. Stops only this invocation's Engine/UI on SIGINT/SIGTERM. Never starts, stops or manages Kubo. No UI unless --ui. Old .mjs configs must be manually migrated. Gateway-only: an explicit URL is required (no credentials/query/fragment); no default node or public Gateway. Base paths are appended with /ipfs/{cid}?format=raw. Raw blocks only, no redirects, 2 MiB/block and 30 s/read. No service RPC or transport selection/fallback; author publishing/pinning is unchanged.",
|
|
51
|
+
};
|
|
52
|
+
console.log(parsed.options.format === "json"
|
|
53
|
+
? JSON.stringify(help)
|
|
54
|
+
: `${help.usage}\n${help.options.join("\n")}\n\n${help.precedence}\nUser config: ${help.globalConfig}\n${help.paths}\n${help.validation}\n${help.isolation}\nDefaults: ${JSON.stringify(help.defaults)}\n${help.security}\n${help.lifecycle}`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (parsed.options.version) {
|
|
58
|
+
console.log(metadata.version);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const config = await resolveConfig(parsed);
|
|
62
|
+
const { startService } = await import("./service.js");
|
|
63
|
+
const service = await startService(config);
|
|
64
|
+
console.log(JSON.stringify({ event: "ready", url: service.url, uiUrl: service.uiUrl, pid: process.pid }));
|
|
65
|
+
let stopping = false;
|
|
66
|
+
const shutdown = () => {
|
|
67
|
+
if (stopping)
|
|
68
|
+
return;
|
|
69
|
+
stopping = true;
|
|
70
|
+
void service.close().then(() => {
|
|
71
|
+
process.removeListener("SIGINT", shutdown);
|
|
72
|
+
process.removeListener("SIGTERM", shutdown);
|
|
73
|
+
console.log(JSON.stringify({ event: "closed" }));
|
|
74
|
+
}, () => {
|
|
75
|
+
console.error("Shutdown failed; physical cleanup unconfirmed.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
process.on("SIGINT", shutdown);
|
|
80
|
+
process.on("SIGTERM", shutdown);
|
|
81
|
+
}
|
|
82
|
+
void main().catch((error) => {
|
|
83
|
+
// Errors from libraries can contain URL credentials or config excerpts.
|
|
84
|
+
console.error(error instanceof ConfigurationError
|
|
85
|
+
? error.message
|
|
86
|
+
: "Invalid configuration or service startup failed; cleanup unconfirmed.");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Authorize, type Caller } from "@potential-guide/task-protocol";
|
|
2
|
+
import { type ServiceConfig } from "./config.js";
|
|
3
|
+
export declare function localPolicy(scope: string, origin: () => string): {
|
|
4
|
+
authorize: Authorize;
|
|
5
|
+
resolveCaller(request: Request): Caller;
|
|
6
|
+
};
|
|
7
|
+
export declare function startService(raw: ServiceConfig): Promise<{
|
|
8
|
+
close(): Promise<void>;
|
|
9
|
+
uiUrl?: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAkB,KAAK,aAAa,EAAiB,MAAM,aAAa,CAAC;AAchF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM;;2BASpC,OAAO,GAAG,MAAM;EAiB1C;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,aAAa;aAwCxC,OAAO,CAAC,IAAI,CAAC;;;GAkBzB"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createIpfsGatewayClient } from "@potential-guide/task-engine";
|
|
2
|
+
import { startTaskServer } from "@potential-guide/task-engine-server";
|
|
3
|
+
import { startUiServer, validateUiConfig } from "@potential-guide/task-engine-webui/server";
|
|
4
|
+
import { TaskError, } from "@potential-guide/task-protocol";
|
|
5
|
+
import { requireGateway, validateLayer } from "./config.js";
|
|
6
|
+
const operations = new Set([
|
|
7
|
+
"submit",
|
|
8
|
+
"request",
|
|
9
|
+
"task",
|
|
10
|
+
"run",
|
|
11
|
+
"cancel",
|
|
12
|
+
"history",
|
|
13
|
+
"subscribe",
|
|
14
|
+
"list",
|
|
15
|
+
"list-runs",
|
|
16
|
+
"message",
|
|
17
|
+
]);
|
|
18
|
+
export function localPolicy(scope, origin) {
|
|
19
|
+
const caller = Object.freeze({ subject: "local-cli", scope });
|
|
20
|
+
const authorize = (identity, operation, target) => identity.subject === caller.subject &&
|
|
21
|
+
identity.scope === scope &&
|
|
22
|
+
target === scope &&
|
|
23
|
+
operations.has(operation);
|
|
24
|
+
return {
|
|
25
|
+
authorize,
|
|
26
|
+
resolveCaller(request) {
|
|
27
|
+
const expected = origin();
|
|
28
|
+
const site = request.headers.get("sec-fetch-site");
|
|
29
|
+
if (!expected ||
|
|
30
|
+
request.headers.get("host") !== new URL(expected).host ||
|
|
31
|
+
(request.headers.has("origin") && request.headers.get("origin") !== expected) ||
|
|
32
|
+
(site !== null && site !== "same-origin" && site !== "none") ||
|
|
33
|
+
!["GET", "POST"].includes(request.method) ||
|
|
34
|
+
(request.method === "POST" &&
|
|
35
|
+
request.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() !==
|
|
36
|
+
"application/json"))
|
|
37
|
+
throw new TaskError("forbidden", "Local service request policy denied access.");
|
|
38
|
+
return caller;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function startService(raw) {
|
|
43
|
+
const config = validateLayer(raw, process.cwd(), "effective configuration");
|
|
44
|
+
requireGateway(config);
|
|
45
|
+
const uiConfig = {
|
|
46
|
+
...config.uiOptions,
|
|
47
|
+
endpoints: [
|
|
48
|
+
{ id: "local", label: "Local Task Engine", binding: config.scope, url: "http://127.0.0.1:1" },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
// All declarative options are checked before any DB or listening socket is opened.
|
|
52
|
+
validateUiConfig(uiConfig);
|
|
53
|
+
let origin = "";
|
|
54
|
+
const policy = localPolicy(config.scope, () => origin);
|
|
55
|
+
const server = await startTaskServer({
|
|
56
|
+
host: config.host,
|
|
57
|
+
port: config.port,
|
|
58
|
+
database: config.database,
|
|
59
|
+
ipfsClient: createIpfsGatewayClient(config.ipfsGatewayUrl),
|
|
60
|
+
...policy,
|
|
61
|
+
});
|
|
62
|
+
origin = server.url;
|
|
63
|
+
let ui;
|
|
64
|
+
try {
|
|
65
|
+
if (config.ui)
|
|
66
|
+
ui = await startUiServer({
|
|
67
|
+
...uiConfig,
|
|
68
|
+
endpoints: [{ ...uiConfig.endpoints[0], url: server.url }],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
try {
|
|
73
|
+
await server.close();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new Error("UI startup and Engine rollback failed; cleanup unconfirmed.");
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
let closing;
|
|
81
|
+
return {
|
|
82
|
+
url: server.url,
|
|
83
|
+
...(ui ? { uiUrl: ui.url } : {}),
|
|
84
|
+
close() {
|
|
85
|
+
closing ??= (async () => {
|
|
86
|
+
const failures = [];
|
|
87
|
+
try {
|
|
88
|
+
await ui?.close();
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
failures.push(error);
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await server.close();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
failures.push(error);
|
|
98
|
+
}
|
|
99
|
+
if (failures.length)
|
|
100
|
+
throw new Error("Service cleanup unconfirmed.");
|
|
101
|
+
})();
|
|
102
|
+
return closing;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@potential-guide/pguide-task-engine",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-rc.0",
|
|
4
|
+
"description": "Declarative local Task Engine service command with optional Web UI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pguide-task-engine": "./dist/main.js"
|
|
8
|
+
},
|
|
9
|
+
"pguide": {
|
|
10
|
+
"settings": "./settings.json"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"settings.json",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"yaml": "2.9.1",
|
|
19
|
+
"@potential-guide/task-engine-webui": "^0.1.0-rc.0",
|
|
20
|
+
"@potential-guide/task-protocol": "^0.1.0-rc.0",
|
|
21
|
+
"@potential-guide/task-engine": "^0.1.0-rc.0",
|
|
22
|
+
"@potential-guide/task-engine-server": "^0.1.0-rc.0",
|
|
23
|
+
"@potential-guide/cli-core": "^0.3.0-rc.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@potential-guide/task-sdk": "^0.1.0-rc.0",
|
|
27
|
+
"@potential-guide/pguide-task-bundle": "^0.1.0-rc.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22.13.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/shazhou-ww/potential-guide.git",
|
|
39
|
+
"directory": "apps/pguide-task-engine"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.json",
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
44
|
+
"lint": "biome lint .",
|
|
45
|
+
"test": "tsx --test \"test/*.test.ts\"",
|
|
46
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""
|
|
47
|
+
}
|
|
6
48
|
}
|
package/settings.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"namespace": "task-engine",
|
|
4
|
+
"settings": {
|
|
5
|
+
"task-engine.host": {
|
|
6
|
+
"description": "Fixed loopback binding; localhost normalizes to 127.0.0.1.",
|
|
7
|
+
"schema": { "enum": ["127.0.0.1", "localhost", "::1"] }
|
|
8
|
+
},
|
|
9
|
+
"task-engine.port": {
|
|
10
|
+
"description": "Engine TCP port; zero selects an available port.",
|
|
11
|
+
"schema": { "type": "integer", "minimum": 0, "maximum": 65535 }
|
|
12
|
+
},
|
|
13
|
+
"task-engine.database": {
|
|
14
|
+
"description": "SQLite filename, relative to the source file directory.",
|
|
15
|
+
"schema": { "type": "string", "minLength": 1 }
|
|
16
|
+
},
|
|
17
|
+
"task-engine.ipfsGatewayUrl": {
|
|
18
|
+
"description": "Required explicit read-only HTTP(S) Trustless Gateway base URL; no credentials, query or fragment. No default node.",
|
|
19
|
+
"schema": { "type": "string", "minLength": 1 }
|
|
20
|
+
},
|
|
21
|
+
"task-engine.scope": {
|
|
22
|
+
"description": "Single local Caller scope. Other scopes are denied.",
|
|
23
|
+
"schema": { "type": "string", "pattern": "^[a-zA-Z0-9_-]{1,64}$" }
|
|
24
|
+
},
|
|
25
|
+
"task-engine.ui": {
|
|
26
|
+
"description": "Start the HTTP-only local Web UI.",
|
|
27
|
+
"schema": { "type": "boolean" }
|
|
28
|
+
},
|
|
29
|
+
"task-engine.uiOptions": {
|
|
30
|
+
"description": "Whole UI setting, replaced rather than deep merged. All properties required.",
|
|
31
|
+
"schema": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": ["host", "port", "favoritesFile"],
|
|
35
|
+
"properties": {
|
|
36
|
+
"host": { "enum": ["127.0.0.1", "localhost", "::1"] },
|
|
37
|
+
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
38
|
+
"favoritesFile": { "type": "string", "minLength": 1 }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|