@gyoungwe/research-suite 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -5,4 +5,6 @@ The suite aggregates the published `@gyoungwe/pi-core`,
5
5
  tarball bundles those dependencies so a Pi host can discover the extensions and
6
6
  skills without a second network resolution step. `research-workflow` comes
7
7
  from `@gyoungwe/pi-research`; `@gyoungwe/pi-knowledge` supplies the Vault and
8
- Show Me skills, so the suite exposes one copy of each skill.
8
+ Show Me skills, so the suite exposes one copy of each skill. `pi-core` also
9
+ provides the stable `/drone-doctor` and `/drone-example` onboarding commands;
10
+ the latter is read-only unless the user explicitly supplies `--run <question>`.
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "version": 1,
3
3
  "generator": "packages/research-suite/scripts/build.mjs",
4
- "packageVersion": "0.1.2",
4
+ "packageVersion": "0.1.3",
5
5
  "bundled": [
6
6
  "@gyoungwe/pi-core",
7
7
  "@gyoungwe/pi-knowledge",
8
8
  "@gyoungwe/pi-research"
9
9
  ],
10
- "dependenciesSha256": "226c3c4a28a71df1f571ff6a977d3798d9ccc0914297292772a636f45abf5716"
10
+ "dependenciesSha256": "b9f96897420917b045d23eab8667a17145c637d2c9784359f8f049e872d1e782"
11
11
  }
@@ -3,6 +3,11 @@
3
3
  Portable Pi extension for Drone's task ledger and user-facing core tools:
4
4
  `ask_user`, `set_status`, `todo`, `deliver_files`, and `memory_save`.
5
5
 
6
+ It also exposes `/drone-doctor` (a stable JSON host/package diagnostic) and
7
+ `/drone-example` (a read-only research example preview, with `--run` for an
8
+ explicit user question). The example reports `needs-data`, `blocked`, `ready`,
9
+ or `started`; it never claims a scientific result without source receipts.
10
+
6
11
  The package also registers the `@drone/tasks` runtime. Native Pi uses the
7
12
  extension context's `ctx.ui`; Drone Desktop can inject its existing ask gate
8
13
  through `registerPiCore(pi, { ask })`. The package has no Electron, backend, or
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": 1,
3
3
  "generator": "scripts/build-pi-core.mjs",
4
- "inputsSha256": "0a7a9931d9c82a304460a498ea8611a741c5eb9cd74c865831058f357f031f73",
4
+ "inputsSha256": "de6fabddabb2c24748d325d3484d0c76bfde8ede915da8225d7f4d47927f282c",
5
5
  "outputs": {
6
- "dist/index.mjs": "34036b70dd1f62e9ec23d3f4f6c9f2ba1a0e085cac6975860bbb587f91ec3a84"
6
+ "dist/index.mjs": "df76a92939ab5d6f32c87d6795cafeabe54a90c2bc952c7efdffbfa806996f1b"
7
7
  }
8
8
  }
@@ -2030,7 +2030,7 @@ function registerWorkbench(pi, options = {}) {
2030
2030
  };
2031
2031
  const journal = createTaskWorkbench({
2032
2032
  requireAuthorization: true,
2033
- persist: (snapshot) => pi.appendEntry(WORKBENCH_ENTRY, snapshot),
2033
+ persist: (snapshot2) => pi.appendEntry(WORKBENCH_ENTRY, snapshot2),
2034
2034
  onCheckpoint: () => send(),
2035
2035
  // 里程碑验收器(zotero_item / wiki_review / …)由各自的扩展 registerAcceptanceVerifier 登记(挂钩 2)
2036
2036
  inspect
@@ -2309,12 +2309,12 @@ ${hostLanguage() === "zh" ? "\uFF08\u4EE5\u4E0B\u4E3A\u5BBF\u4E3B\u7EA6\u675F\uF
2309
2309
  continueAuthorized(turnContext);
2310
2310
  return;
2311
2311
  }
2312
- const snapshot = journal.snapshot();
2313
- if (last?.stopReason !== "error" && !ctx?.signal?.aborted && shouldAskToContinue(snapshot ? journal.view().tasks.find((t) => t.id === snapshot.id) : null)) {
2312
+ const snapshot2 = journal.snapshot();
2313
+ if (last?.stopReason !== "error" && !ctx?.signal?.aborted && shouldAskToContinue(snapshot2 ? journal.view().tasks.find((t) => t.id === snapshot2.id) : null)) {
2314
2314
  send();
2315
2315
  try {
2316
2316
  if (activeSessionId !== turnSessionId || context !== turnContext) return;
2317
- await progressTask({ taskId: snapshot.id, revision: journal.view().revision }, turnContext);
2317
+ await progressTask({ taskId: snapshot2.id, revision: journal.view().revision }, turnContext);
2318
2318
  } catch {
2319
2319
  }
2320
2320
  return;
@@ -2748,7 +2748,7 @@ function createTaskJournal({ persist = () => {
2748
2748
  }
2749
2749
  function registerTaskRuntime(pi, options = {}) {
2750
2750
  if (process.env.DRONE_TASK_WORKBENCH !== "off") return registerWorkbench(pi, options);
2751
- const journal = createTaskJournal({ persist: (snapshot) => pi.appendEntry?.(TASK_ENTRY, snapshot) });
2751
+ const journal = createTaskJournal({ persist: (snapshot2) => pi.appendEntry?.(TASK_ENTRY, snapshot2) });
2752
2752
  const attach = (ctx, force = false) => {
2753
2753
  const id = ctx.sessionManager?.getSessionId?.() || ctx.sessionId || "isolated";
2754
2754
  const scope = createHash4("sha256").update(`${id}\0${resolve5(ctx.cwd)}`).digest("hex");
@@ -17309,6 +17309,136 @@ ${formatTodoList(todos)}`;
17309
17309
  };
17310
17310
  }
17311
17311
 
17312
+ // src/drone-commands.ts
17313
+ import { readFileSync as readFileSync2 } from "node:fs";
17314
+ import { createRequire } from "node:module";
17315
+ import { dirname, join as join3 } from "node:path";
17316
+ var DRONE_COMMAND_SCHEMA_VERSION = 1;
17317
+ var PI_CORE_PACKAGE_VERSION = "0.1.1";
17318
+ var PI_HOST_RANGE = ">=1.1.0 <2.0.0";
17319
+ var CORE_TOOLS = [
17320
+ "ask_user",
17321
+ "set_status",
17322
+ "todo",
17323
+ "deliver_files",
17324
+ "memory_save",
17325
+ "task_plan",
17326
+ "task_status",
17327
+ "task_wait",
17328
+ "task_reconcile",
17329
+ "task_evidence_restore"
17330
+ ];
17331
+ var EXAMPLE_TOOLS = [
17332
+ "knowledge_status",
17333
+ "knowledge_search",
17334
+ "research_search_sources",
17335
+ "research_read_source",
17336
+ "research_answer_sources"
17337
+ ];
17338
+ function packageVersion() {
17339
+ const configured = process.env.PI_VERSION?.trim();
17340
+ if (configured) return { version: configured, source: "PI_VERSION" };
17341
+ try {
17342
+ const require2 = createRequire(import.meta.url);
17343
+ const entry = require2.resolve("@earendil-works/pi-coding-agent");
17344
+ const packagePath = join3(dirname(entry), "..", "package.json");
17345
+ const metadata = JSON.parse(readFileSync2(packagePath, "utf8"));
17346
+ if (typeof metadata.version === "string" && metadata.version.length > 0)
17347
+ return { version: metadata.version, source: "resolved-package" };
17348
+ } catch {
17349
+ }
17350
+ return { version: null, source: "unavailable" };
17351
+ }
17352
+ function snapshot(pi) {
17353
+ const tools = typeof pi?.getAllTools === "function" ? pi.getAllTools().map((tool) => String(tool?.name || "")).filter(Boolean) : typeof pi?.getActiveTools === "function" ? pi.getActiveTools().map((name) => String(name)).filter(Boolean) : [];
17354
+ const commands = typeof pi?.getCommands === "function" ? pi.getCommands().map((command) => String(command?.name || "")).filter(Boolean) : [];
17355
+ return { tools: [...new Set(tools)].sort(), commands: [...new Set(commands)].sort() };
17356
+ }
17357
+ function buildDoctorReport(pi, options = {}) {
17358
+ const current = snapshot(pi);
17359
+ const missingTools = CORE_TOOLS.filter((name) => !current.tools.includes(name));
17360
+ const missingCommands = ["drone-doctor", "drone-example"].filter((name) => !current.commands.includes(name));
17361
+ const resolved = options.hostVersion === void 0 ? packageVersion() : { version: options.hostVersion, source: "host-contract" };
17362
+ const hostKind = options.hostKind || "native-pi";
17363
+ const checks = [
17364
+ {
17365
+ id: "core-tools",
17366
+ status: missingTools.length ? "blocked" : "pass",
17367
+ detail: missingTools.length ? "pi-core tools are missing" : "all pi-core tools are registered",
17368
+ ...missingTools.length ? { missing: missingTools } : {}
17369
+ },
17370
+ {
17371
+ id: "drone-commands",
17372
+ status: missingCommands.length ? "blocked" : "pass",
17373
+ detail: missingCommands.length ? "Drone onboarding commands are missing" : "doctor and example commands are registered",
17374
+ ...missingCommands.length ? { missing: missingCommands } : {}
17375
+ },
17376
+ {
17377
+ id: "pi-host-version",
17378
+ status: resolved.version ? "pass" : "unknown",
17379
+ detail: resolved.version ? `resolved Pi host ${resolved.version}` : "Pi host version is not exposed by this host"
17380
+ }
17381
+ ];
17382
+ const blocked = checks.some((check) => check.status === "blocked");
17383
+ return {
17384
+ schemaVersion: DRONE_COMMAND_SCHEMA_VERSION,
17385
+ command: "drone-doctor",
17386
+ status: blocked ? "blocked" : resolved.version ? "pass" : "unknown",
17387
+ plugin: { name: "@gyoungwe/pi-core", version: PI_CORE_PACKAGE_VERSION, piRange: PI_HOST_RANGE },
17388
+ host: { kind: hostKind, version: resolved.version || null, source: resolved.source },
17389
+ checks,
17390
+ commands: current.commands,
17391
+ tools: current.tools,
17392
+ next: blocked ? "\u5B89\u88C5\u6216\u91CD\u65B0\u52A0\u8F7D\u7F3A\u5931\u7684 Drone \u63D2\u4EF6\u540E\u91CD\u8BD5 /drone-doctor" : null
17393
+ };
17394
+ }
17395
+ function buildExampleReport(pi, mode = "preview", question) {
17396
+ const current = snapshot(pi);
17397
+ const missingTools = EXAMPLE_TOOLS.filter((name) => !current.tools.includes(name));
17398
+ const hasQuestion = Boolean(question?.trim());
17399
+ const status2 = missingTools.length ? "blocked" : mode === "run" && hasQuestion ? "started" : hasQuestion ? "ready" : "needs-data";
17400
+ return {
17401
+ schemaVersion: DRONE_COMMAND_SCHEMA_VERSION,
17402
+ command: "drone-example",
17403
+ status: status2,
17404
+ mode,
17405
+ title: "Evidence-gated local research example",
17406
+ steps: ["inspect local knowledge", "read at least two sources", "answer with source receipts"],
17407
+ requiredTools: [...EXAMPLE_TOOLS],
17408
+ missingTools: [...missingTools],
17409
+ next: missingTools.length ? "\u5B89\u88C5\u5E76\u542F\u7528 pi-knowledge \u4E0E pi-research \u540E\u91CD\u8BD5 /drone-example" : hasQuestion ? mode === "run" ? "\u7814\u7A76\u56DE\u5408\u5DF2\u6392\u961F\uFF1B\u7B49\u5F85\u771F\u5B9E\u6765\u6E90\u56DE\u6267" : "\u8FD0\u884C /drone-example --run <\u7814\u7A76\u95EE\u9898> \u5F00\u59CB\u53EA\u8BFB\u793A\u4F8B" : "\u63D0\u4F9B\u4E00\u4E2A\u7814\u7A76\u95EE\u9898\uFF1A/drone-example --run <\u7814\u7A76\u95EE\u9898>",
17410
+ ...hasQuestion ? { question: question?.trim() } : {}
17411
+ };
17412
+ }
17413
+ function emitReport(report, ctx) {
17414
+ const message = JSON.stringify(report);
17415
+ if (ctx.mode === "print" || ctx.mode === "json") console.log(message);
17416
+ else ctx.ui.notify(message, report.status === "blocked" ? "warning" : "info");
17417
+ }
17418
+ function registerDroneCommands(pi, options = {}) {
17419
+ pi.registerCommand("drone-doctor", {
17420
+ description: "Check the resolved Pi host, core tools and Drone command contract",
17421
+ handler: async (_args, ctx) => emitReport(buildDoctorReport(pi, options), ctx)
17422
+ });
17423
+ pi.registerCommand("drone-example", {
17424
+ description: "Preview or start a read-only evidence-gated research example",
17425
+ handler: async (args, ctx) => {
17426
+ const trimmed = args.trim();
17427
+ const run = trimmed.startsWith("--run");
17428
+ const question = run ? trimmed.slice("--run".length).trim() : trimmed;
17429
+ const report = buildExampleReport(pi, run ? "run" : "preview", question || void 0);
17430
+ if (run && report.status === "started" && typeof pi.sendUserMessage === "function") {
17431
+ await pi.sendUserMessage(
17432
+ `Run a read-only Drone research example for this question: ${question}
17433
+ Use local evidence first, read at least two sources, preserve source URIs and hashes, and report blocked/unknown states instead of guessing.`,
17434
+ { deliverAs: "followUp", expandPromptTemplates: true }
17435
+ );
17436
+ }
17437
+ emitReport(report, ctx);
17438
+ }
17439
+ });
17440
+ }
17441
+
17312
17442
  // src/index.ts
17313
17443
  var DEFAULT_HOST_VERSION = "1.1.0";
17314
17444
  function createNativePiHostPort(ctx, hostVersion = DEFAULT_HOST_VERSION) {
@@ -17381,6 +17511,7 @@ function registerPiCore(pi, options = {}) {
17381
17511
  activeContext = void 0;
17382
17512
  });
17383
17513
  registerTaskRuntime(pi);
17514
+ registerDroneCommands(pi, { hostKind: options.host?.host === "drone-desktop" ? "drone-desktop" : "native-pi" });
17384
17515
  const ask = options.ask || ((request, signal, context) => askWithNativeUi(request, signal, context || activeContext));
17385
17516
  pi.registerTool(makeAskUserTool({ ask }));
17386
17517
  pi.registerTool(makeStatusTool());
@@ -17394,7 +17525,12 @@ function registerPiCore(pi, options = {}) {
17394
17525
  }
17395
17526
  var index_default = registerPiCore;
17396
17527
  export {
17528
+ DRONE_COMMAND_SCHEMA_VERSION,
17397
17529
  MEMORY_SAVE_TOOL,
17530
+ PI_CORE_PACKAGE_VERSION,
17531
+ PI_HOST_RANGE,
17532
+ buildDoctorReport,
17533
+ buildExampleReport,
17398
17534
  createNativePiHostPort,
17399
17535
  index_default as default,
17400
17536
  deliverFilesParams,
@@ -17407,6 +17543,7 @@ export {
17407
17543
  makeTodoTool,
17408
17544
  memoryIndexPrompt,
17409
17545
  normalizeTodos,
17546
+ registerDroneCommands,
17410
17547
  registerPiCore,
17411
17548
  writeMemory
17412
17549
  };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gyoungwe/pi-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Portable task, authorization, status, delivery and memory tools for native Pi",
5
5
  "keywords": [
6
6
  "pi-package"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gyoungwe/research-suite",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Bundled Drone native Pi research suite",
5
5
  "keywords": ["pi-package", "research", "evidence"],
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "prompts": ["./prompts/*.md"]
32
32
  },
33
33
  "dependencies": {
34
- "@gyoungwe/pi-core": "0.1.0",
34
+ "@gyoungwe/pi-core": "0.1.1",
35
35
  "@gyoungwe/pi-knowledge": "0.1.1",
36
36
  "@gyoungwe/pi-research": "0.1.0"
37
37
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "drone-research-suite",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "pi": {
6
6
  "apiVersion": 1,
7
7
  "minHostVersion": "1.1.0",