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.
Files changed (2) hide show
  1. package/dist/index.js +92 -4
  2. 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: op.id,
2354
+ artifactId: spawnId,
2280
2355
  kind: "spawn_artifact",
2281
- target: op.id,
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(op.id) ? "prereq" : "manual-spawn",
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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
5
5
  "bin": {
6
6
  "oasis": "./dist/index.js"