oasis_test 0.1.12 → 0.1.13
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/index.js +92 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -618,6 +618,20 @@ function deriveArtifactId(type, workspace, title, usedIds) {
|
|
|
618
618
|
usedIds.add(id);
|
|
619
619
|
return id;
|
|
620
620
|
}
|
|
621
|
+
function resolveNodeRef(ref, candidates) {
|
|
622
|
+
const r = ref.trim();
|
|
623
|
+
if (r.startsWith("artifact:")) {
|
|
624
|
+
const hit = candidates.find((n) => n.id === r);
|
|
625
|
+
return hit ? { ok: true, id: hit.id } : { ok: false, reason: "not_found" };
|
|
626
|
+
}
|
|
627
|
+
const sep = r.indexOf(":");
|
|
628
|
+
const type = (sep >= 0 ? r.slice(0, sep) : r).trim().toLowerCase();
|
|
629
|
+
const title = sep >= 0 ? r.slice(sep + 1).trim().toLowerCase() : null;
|
|
630
|
+
const matches = candidates.filter((n) => n.type.toLowerCase() === type && (title === null || (n.title ?? "").toLowerCase() === title));
|
|
631
|
+
if (matches.length === 0) return { ok: false, reason: "not_found" };
|
|
632
|
+
if (matches.length === 1) return { ok: true, id: matches[0].id };
|
|
633
|
+
return { ok: false, reason: "ambiguous", candidates: matches };
|
|
634
|
+
}
|
|
621
635
|
var init_node_identity = __esm({
|
|
622
636
|
"../core/src/node-identity.ts"() {
|
|
623
637
|
"use strict";
|
|
@@ -1321,6 +1335,7 @@ var init_kernel = __esm({
|
|
|
1321
1335
|
init_src();
|
|
1322
1336
|
init_read_model();
|
|
1323
1337
|
init_content_handler();
|
|
1338
|
+
init_node_identity();
|
|
1324
1339
|
init_governance();
|
|
1325
1340
|
init_manifest_store();
|
|
1326
1341
|
init_grounding();
|
|
@@ -2060,7 +2075,64 @@ var init_kernel = __esm({
|
|
|
2060
2075
|
* 预检(②终态校验 + ③advisory + ④爆炸半径)。preview 白送:
|
|
2061
2076
|
* structuredClone 读模型、灌假设 op、看终态——derived-not-stored 的红利,无须仿真引擎。
|
|
2062
2077
|
*/
|
|
2078
|
+
/**
|
|
2079
|
+
* 二期 title-identity:把 plan 里的【节点引用】(`type` | `type:title` | `id`)解析成最终 id。
|
|
2080
|
+
* - spawn 省略 id → 据 (type,title) 派生(usedIds 预种工单现有 id + 本批显式 id,不和存量撞)。
|
|
2081
|
+
* - 引用现有/本批节点 → 在 plan.workspace 范围内 {现有 ∪ 本批 spawn} 匹配;撞多个 throw 带候选、无则 throw。
|
|
2082
|
+
* - 批内**先派生所有 spawn 的 id,再解引用**(link 才引得到本批新建的)。
|
|
2083
|
+
* - workspace 缺省 = 只走 id(向后兼容 passthrough)。**幂等**:解析一份已解析的 plan = 原样。
|
|
2084
|
+
* 落 oplog 的是解析后的 id(重放确定)。
|
|
2085
|
+
*/
|
|
2086
|
+
resolveInterventionRefs(plan) {
|
|
2087
|
+
const ws = plan.workspace;
|
|
2088
|
+
const existing = ws ? [...this.model.artifacts.values()].filter((a) => a.workspace === ws).map((a) => ({ id: a.id, type: a.type, ...a.title ? { title: a.title } : {} })) : [];
|
|
2089
|
+
const usedIds = new Set(existing.map((n) => n.id));
|
|
2090
|
+
for (const op of plan.ops) if (op.action === "spawn" && op.id) usedIds.add(op.id);
|
|
2091
|
+
const batch = [];
|
|
2092
|
+
const spawnIds = plan.ops.map((op) => {
|
|
2093
|
+
if (op.action !== "spawn") return void 0;
|
|
2094
|
+
if (op.id) {
|
|
2095
|
+
batch.push({ id: op.id, type: op.type, ...op.title ? { title: op.title } : {} });
|
|
2096
|
+
return op.id;
|
|
2097
|
+
}
|
|
2098
|
+
if (!ws) throw new KernelError("spawn \u7701\u7565 id \u9700\u8981 InterventionPlan.workspace + title \u624D\u80FD\u6D3E\u751F");
|
|
2099
|
+
const title = op.title?.trim();
|
|
2100
|
+
if (!title) throw new KernelError("spawn \u7701\u7565 id \u65F6 title \u5FC5\u586B\uFF08\u636E (type,title) \u6D3E\u751F id\uFF09");
|
|
2101
|
+
if ([...existing, ...batch].some((n) => n.type === op.type && (n.title ?? "").toLowerCase() === title.toLowerCase()))
|
|
2102
|
+
throw new KernelError(`\u8282\u70B9 title \u649E\u540D\uFF1A${op.type}\u300C${title}\u300D\u5728\u672C\u5DE5\u5355\u5DF2\u5B58\u5728,\u8BF7\u6362\u4E2A\u533A\u5206\u7684\u540D\u5B57`);
|
|
2103
|
+
const id = deriveArtifactId(op.type, ws, title, usedIds);
|
|
2104
|
+
batch.push({ id, type: op.type, title });
|
|
2105
|
+
return id;
|
|
2106
|
+
});
|
|
2107
|
+
const candidates = [...existing, ...batch];
|
|
2108
|
+
const ref = (r, what) => {
|
|
2109
|
+
if (r === void 0) return void 0;
|
|
2110
|
+
if (!ws) return r;
|
|
2111
|
+
const res = resolveNodeRef(r, candidates);
|
|
2112
|
+
if (res.ok) return res.id;
|
|
2113
|
+
if (res.reason === "ambiguous")
|
|
2114
|
+
throw new KernelError(`${what}\u300C${r}\u300D\u5339\u914D\u5230\u591A\u4E2A\u8282\u70B9,\u8BF7\u6307\u660E\u54EA\u4E2A:
|
|
2115
|
+
${res.candidates.map((c) => ` - ${c.type}:${c.title ?? "(\u65E0title)"} \u2192 ${c.id}`).join("\n")}`);
|
|
2116
|
+
throw new KernelError(`${what}\u300C${r}\u300D\u627E\u4E0D\u5230\u5BF9\u5E94\u8282\u70B9\uFF08\u53EF\u7528 type / type:title / id\uFF09`);
|
|
2117
|
+
};
|
|
2118
|
+
const ops = plan.ops.map((op, i) => {
|
|
2119
|
+
switch (op.action) {
|
|
2120
|
+
case "spawn":
|
|
2121
|
+
return { ...op, id: spawnIds[i], ...op.workspace === void 0 && ws ? { workspace: ws } : {}, ...op.inputs ? { inputs: op.inputs.map((e) => ({ to: ref(e.to, "spawn \u4F9D\u8D56"), ...e.required !== void 0 ? { required: e.required } : {} })) } : {} };
|
|
2122
|
+
case "link":
|
|
2123
|
+
case "unlink":
|
|
2124
|
+
case "pin":
|
|
2125
|
+
return { ...op, artifactId: ref(op.artifactId, op.action), to: ref(op.to, `${op.action} \u4E0A\u6E38`) };
|
|
2126
|
+
case "annotate":
|
|
2127
|
+
return { ...op, artifactId: ref(op.artifactId, "annotate"), ...op.raisedFrom ? { raisedFrom: ref(op.raisedFrom, "annotate raisedFrom") } : {} };
|
|
2128
|
+
default:
|
|
2129
|
+
return { ...op, artifactId: ref(op.artifactId, op.action) };
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
2132
|
+
return { ...plan, ops };
|
|
2133
|
+
}
|
|
2063
2134
|
async previewIntervention(plan) {
|
|
2135
|
+
plan = this.resolveInterventionRefs(plan);
|
|
2064
2136
|
const constituents = this.buildConstituents(plan);
|
|
2065
2137
|
const touched = [...new Set(constituents.map((c) => c.artifactId))];
|
|
2066
2138
|
const baseSeqs = Object.fromEntries(touched.map((id) => [id, this.model.lastSeq.get(id) ?? 0]));
|
|
@@ -2189,6 +2261,7 @@ var init_kernel = __esm({
|
|
|
2189
2261
|
* v1 注:inverse 批次未物化(oplog 信息足以推导),可逆性=再发一个 intervention。
|
|
2190
2262
|
*/
|
|
2191
2263
|
async applyIntervention(plan, baseSeqs, actor) {
|
|
2264
|
+
plan = this.resolveInterventionRefs(plan);
|
|
2192
2265
|
const { changeClass, nonMonotonicOps } = classifyIntervention(plan);
|
|
2193
2266
|
if (changeClass === "C" && !isHumanActor(actor)) {
|
|
2194
2267
|
throw new KernelError(
|
|
@@ -2266,25 +2339,27 @@ var init_kernel = __esm({
|
|
|
2266
2339
|
buildConstituentsRaw(plan) {
|
|
2267
2340
|
const order = { spawn: 0, edit: 1, reopen: 2, assign: 3, link: 4, pin: 5, unlink: 6, cancelPart: 7, seal: 8, annotate: 9 };
|
|
2268
2341
|
const sorted = [...plan.ops].sort((a, b2) => order[a.action] - order[b2.action]);
|
|
2269
|
-
const spawnedHere = new Set(plan.ops.flatMap((op) => op.action === "spawn" ? [op.id] : []));
|
|
2342
|
+
const spawnedHere = new Set(plan.ops.flatMap((op) => op.action === "spawn" && op.id ? [op.id] : []));
|
|
2270
2343
|
const isPrereqFill = (id) => plan.ops.some((op) => op.action === "link" && op.to === id && !spawnedHere.has(op.artifactId));
|
|
2271
2344
|
return sorted.map((op) => {
|
|
2272
2345
|
switch (op.action) {
|
|
2273
2346
|
case "spawn": {
|
|
2347
|
+
const spawnId = op.id;
|
|
2348
|
+
if (!spawnId) throw new KernelError("internal: spawn id \u672A\u89E3\u6790\uFF08\u5E94\u5148\u8FC7 resolveInterventionRefs\uFF09");
|
|
2274
2349
|
const typeDef = this.schema.get(op.type);
|
|
2275
2350
|
if (this.schema.size > 0 && !typeDef) throw new KernelError(`unknown ArtifactType: ${op.type}`);
|
|
2276
2351
|
const spawnFields = this.schema.size > 0 ? validateArtifactFields(op.fields, typeDef?.fieldDefs, "spawn") : op.fields;
|
|
2277
2352
|
const owner = op.owner ?? this.resolveOwner(op.type, typeDef);
|
|
2278
2353
|
return {
|
|
2279
|
-
artifactId:
|
|
2354
|
+
artifactId: spawnId,
|
|
2280
2355
|
kind: "spawn_artifact",
|
|
2281
|
-
target:
|
|
2356
|
+
target: spawnId,
|
|
2282
2357
|
payload: {
|
|
2283
2358
|
type: op.type,
|
|
2284
2359
|
owner,
|
|
2285
2360
|
workspace: op.workspace ?? "ws:default",
|
|
2286
2361
|
persistence: "persistent",
|
|
2287
|
-
createdVia: isPrereqFill(
|
|
2362
|
+
createdVia: isPrereqFill(spawnId) ? "prereq" : "manual-spawn",
|
|
2288
2363
|
...op.title !== void 0 ? { title: op.title } : {},
|
|
2289
2364
|
...op.description !== void 0 ? { description: op.description } : {},
|
|
2290
2365
|
...op.docType !== void 0 ? { docType: op.docType } : {},
|
|
@@ -32484,6 +32559,7 @@ After=network.target
|
|
|
32484
32559
|
|
|
32485
32560
|
[Service]
|
|
32486
32561
|
ExecStart=$NODE_CMD node --server-ws ${p2.gatewayUrl} --dir $NODE_DIR
|
|
32562
|
+
Environment=PATH=$PATH:$HOME/.npm-global/bin:$HOME/.local/bin:/usr/local/bin
|
|
32487
32563
|
WorkingDirectory=$OASIS_DIR
|
|
32488
32564
|
Restart=on-failure
|
|
32489
32565
|
RestartSec=5
|
|
@@ -47313,6 +47389,9 @@ async function runCli(argv, println = console.log) {
|
|
|
47313
47389
|
"",
|
|
47314
47390
|
"[Service]",
|
|
47315
47391
|
`ExecStart=${binPath} ${svcArgs}`,
|
|
47392
|
+
// Carry the install-time PATH so the detached daemon detects CLIs in user dirs
|
|
47393
|
+
// (~/.npm-global/bin, ~/.local/bin) — systemd --user otherwise gives a minimal PATH.
|
|
47394
|
+
`Environment=PATH=${process.env["PATH"] ?? ""}:${path12.join(os7.homedir(), ".npm-global/bin")}:${path12.join(os7.homedir(), ".local/bin")}:/usr/local/bin`,
|
|
47316
47395
|
"Restart=on-failure",
|
|
47317
47396
|
"RestartSec=5",
|
|
47318
47397
|
"StandardOutput=journal",
|
|
@@ -48417,6 +48496,13 @@ exec node "${BIN_FILE}" "$@"
|
|
|
48417
48496
|
}
|
|
48418
48497
|
function setupAutostart() {
|
|
48419
48498
|
const cmd = `${process.execPath} "${BIN_FILE}" --_daemon`;
|
|
48499
|
+
const home = os8.homedir();
|
|
48500
|
+
const extraBins = [
|
|
48501
|
+
path13.join(home, ".npm-global", "bin"),
|
|
48502
|
+
path13.join(home, ".local", "bin"),
|
|
48503
|
+
"/usr/local/bin"
|
|
48504
|
+
];
|
|
48505
|
+
const daemonPath = [process.env["PATH"] ?? "", ...extraBins].filter(Boolean).join(":");
|
|
48420
48506
|
if (process.platform === "linux") {
|
|
48421
48507
|
const unitDir = path13.join(os8.homedir(), ".config", "systemd", "user");
|
|
48422
48508
|
fs15.mkdirSync(unitDir, { recursive: true });
|
|
@@ -48427,6 +48513,7 @@ function setupAutostart() {
|
|
|
48427
48513
|
"",
|
|
48428
48514
|
"[Service]",
|
|
48429
48515
|
`ExecStart=${cmd}`,
|
|
48516
|
+
`Environment=PATH=${daemonPath}`,
|
|
48430
48517
|
`StandardOutput=append:${LOG_FILE}`,
|
|
48431
48518
|
`StandardError=append:${LOG_FILE}`,
|
|
48432
48519
|
"Restart=on-failure",
|
|
@@ -48448,6 +48535,7 @@ function setupAutostart() {
|
|
|
48448
48535
|
<plist version="1.0"><dict>
|
|
48449
48536
|
<key>Label</key><string>com.oasis.node</string>
|
|
48450
48537
|
<key>ProgramArguments</key><array><string>/bin/sh</string><string>-c</string><string>${cmd}</string></array>
|
|
48538
|
+
<key>EnvironmentVariables</key><dict><key>PATH</key><string>${daemonPath}</string></dict>
|
|
48451
48539
|
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
|
|
48452
48540
|
<key>StandardOutPath</key><string>${LOG_FILE}</string>
|
|
48453
48541
|
<key>StandardErrorPath</key><string>${LOG_FILE}</string>
|