@gyoungwe/research-suite 0.1.1 → 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 +8 -9
- package/build-manifest.json +11 -0
- package/node_modules/@gyoungwe/pi-core/README.md +5 -0
- package/node_modules/@gyoungwe/pi-core/build-manifest.json +2 -2
- package/node_modules/@gyoungwe/pi-core/dist/index.mjs +142 -5
- package/node_modules/@gyoungwe/pi-core/package.json +1 -1
- package/node_modules/@gyoungwe/pi-knowledge/README.md +5 -0
- package/node_modules/@gyoungwe/pi-knowledge/build-manifest.json +1 -2
- package/node_modules/@gyoungwe/pi-knowledge/dist/index.mjs +4 -1
- package/node_modules/@gyoungwe/pi-knowledge/package.json +1 -1
- package/node_modules/@gyoungwe/pi-knowledge/plugin.manifest.json +1 -1
- package/node_modules/@gyoungwe/pi-knowledge/skills/research-vault/SKILL.md +1 -1
- package/package.json +44 -56
- package/plugin.manifest.json +1 -1
- package/node_modules/@gyoungwe/pi-knowledge/skills/research-workflow/SKILL.md +0 -103
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# @gyoungwe/research-suite
|
|
2
2
|
|
|
3
|
-
The suite
|
|
4
|
-
`@gyoungwe/pi-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
gates; install the published package with `pi install npm:@gyoungwe/research-suite`.
|
|
3
|
+
The suite aggregates the published `@gyoungwe/pi-core`,
|
|
4
|
+
`@gyoungwe/pi-knowledge`, and `@gyoungwe/pi-research` packages. The release
|
|
5
|
+
tarball bundles those dependencies so a Pi host can discover the extensions and
|
|
6
|
+
skills without a second network resolution step. `research-workflow` comes
|
|
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. `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>`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"generator": "packages/research-suite/scripts/build.mjs",
|
|
4
|
+
"packageVersion": "0.1.3",
|
|
5
|
+
"bundled": [
|
|
6
|
+
"@gyoungwe/pi-core",
|
|
7
|
+
"@gyoungwe/pi-knowledge",
|
|
8
|
+
"@gyoungwe/pi-research"
|
|
9
|
+
],
|
|
10
|
+
"dependenciesSha256": "b9f96897420917b045d23eab8667a17145c637d2c9784359f8f049e872d1e782"
|
|
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": "
|
|
4
|
+
"inputsSha256": "de6fabddabb2c24748d325d3484d0c76bfde8ede915da8225d7f4d47927f282c",
|
|
5
5
|
"outputs": {
|
|
6
|
-
"dist/index.mjs": "
|
|
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: (
|
|
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
|
|
2313
|
-
if (last?.stopReason !== "error" && !ctx?.signal?.aborted && shouldAskToContinue(
|
|
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:
|
|
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: (
|
|
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
|
};
|
|
@@ -10,6 +10,11 @@ The package is intentionally honest on first run: `knowledge_status` returns
|
|
|
10
10
|
exists. The package does not create a Vault implicitly and does not change the
|
|
11
11
|
existing `.pi/` or Vault file formats.
|
|
12
12
|
|
|
13
|
+
Task authorization and progress tools (`task_*`, `task-status` and
|
|
14
|
+
`task-action`) are provided by `@gyoungwe/pi-core`; this package registers only
|
|
15
|
+
knowledge and research tools. The `research-workflow` skill is owned by
|
|
16
|
+
`@gyoungwe/pi-research` and is intentionally not bundled here.
|
|
17
|
+
|
|
13
18
|
The bundle is produced by the host build and committed here as the release
|
|
14
19
|
artifact. The external repository deliberately does not rebuild private Drone
|
|
15
20
|
source; `npm run build` verifies the checked-in artifact and refreshes its
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
"generator": "packages/pi-knowledge/scripts/build.mjs",
|
|
4
4
|
"artifactSource": "drone-host-bundle",
|
|
5
5
|
"outputs": {
|
|
6
|
-
"dist/index.mjs": "
|
|
6
|
+
"dist/index.mjs": "4264546d37c0962cd595eb30b4cfa648528bdb3c6ac91b1b26636a2075dde65a",
|
|
7
7
|
"lib/knowledge/runtime/worker.mjs": "c513d323bcd7827158c4463ca2a2661bd093dc2b2730d2bed48bfb05dd388f44"
|
|
8
8
|
},
|
|
9
9
|
"skills": [
|
|
10
10
|
"skills/research-vault/SKILL.md",
|
|
11
|
-
"skills/research-workflow/SKILL.md",
|
|
12
11
|
"skills/research-show-me/SKILL.md"
|
|
13
12
|
]
|
|
14
13
|
}
|
|
@@ -11126,7 +11126,10 @@ function explainerCard(event) {
|
|
|
11126
11126
|
function registerKnowledgeInterface(pi, { readOnly: readOnly2 = false, runtime = null } = {}) {
|
|
11127
11127
|
bindAcceptanceVerifierEvents(pi);
|
|
11128
11128
|
registerWikiReviewAcceptance();
|
|
11129
|
-
|
|
11129
|
+
// Task authorization/status tools belong to @gyoungwe/pi-core. Keeping the
|
|
11130
|
+
// knowledge extension focused on Vault/research avoids duplicate task_*
|
|
11131
|
+
// registrations when both packages are loaded by a native Pi host.
|
|
11132
|
+
const taskRuntime = null;
|
|
11130
11133
|
const recovery = /* @__PURE__ */ new Map();
|
|
11131
11134
|
let recoveryScope = null;
|
|
11132
11135
|
const saveRecovery = () => {
|
|
@@ -140,4 +140,4 @@ The Wiki review UI also offers **模型自动审核** for one selected candidate
|
|
|
140
140
|
|
|
141
141
|
The reviewer sees only the exact candidate, protected human text and recorded source ranges. It cannot search, write, approve through a tool, or borrow the main conversation's context. Missing evidence, unresolved cautions, version changes and cancellation prevent automatic application. Records distinguish `reviewMethod=model`, `humanReviewed=false` and `scientificallyVerified=false`; do not describe model-approved knowledge as human-verified or scientifically proven.
|
|
142
142
|
|
|
143
|
-
A clean installation ships first-party `research-vault
|
|
143
|
+
A clean installation ships first-party `research-vault` and `research-show-me` from this package. The `research-workflow` skill is supplied by `@gyoungwe/pi-research` so a suite install discovers one canonical copy. Prefer the user's loaded `show-me` when available, otherwise identify the bundled research-show-me fallback honestly. User-installed third-party skills, MCP credentials and literature subscriptions are not included in a release.
|
package/package.json
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"@gyoungwe/pi-core": "0.1.0",
|
|
47
|
-
"@gyoungwe/pi-knowledge": "0.1.0",
|
|
48
|
-
"@gyoungwe/pi-research": "0.1.0"
|
|
49
|
-
},
|
|
50
|
-
"bundleDependencies": [
|
|
51
|
-
"@gyoungwe/pi-core",
|
|
52
|
-
"@gyoungwe/pi-knowledge",
|
|
53
|
-
"@gyoungwe/pi-research"
|
|
54
|
-
],
|
|
55
|
-
"peerDependencies": {
|
|
56
|
-
"@earendil-works/pi-coding-agent": ">=1.1.0 <2.0.0"
|
|
57
|
-
}
|
|
2
|
+
"name": "@gyoungwe/research-suite",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Bundled Drone native Pi research suite",
|
|
5
|
+
"keywords": ["pi-package", "research", "evidence"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {"access": "public"},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Gyoungwe/drone-plugins.git",
|
|
11
|
+
"directory": "packages/research-suite"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"files": ["package.json", "plugin.manifest.json", "README.md", "build-manifest.json", "prompts"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "node scripts/build.mjs",
|
|
17
|
+
"build:check": "node scripts/build.mjs --check",
|
|
18
|
+
"typecheck": "node -e \"process.exit(0)\""
|
|
19
|
+
},
|
|
20
|
+
"pi": {
|
|
21
|
+
"extensions": [
|
|
22
|
+
"./node_modules/@gyoungwe/pi-core/dist/index.mjs",
|
|
23
|
+
"./node_modules/@gyoungwe/pi-knowledge/dist/index.mjs",
|
|
24
|
+
"./node_modules/@gyoungwe/pi-research/dist/index.mjs"
|
|
25
|
+
],
|
|
26
|
+
"skills": [
|
|
27
|
+
"./node_modules/@gyoungwe/pi-core/skills/*",
|
|
28
|
+
"./node_modules/@gyoungwe/pi-knowledge/skills/*",
|
|
29
|
+
"./node_modules/@gyoungwe/pi-research/skills/*"
|
|
30
|
+
],
|
|
31
|
+
"prompts": ["./prompts/*.md"]
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@gyoungwe/pi-core": "0.1.1",
|
|
35
|
+
"@gyoungwe/pi-knowledge": "0.1.1",
|
|
36
|
+
"@gyoungwe/pi-research": "0.1.0"
|
|
37
|
+
},
|
|
38
|
+
"bundleDependencies": [
|
|
39
|
+
"@gyoungwe/pi-core",
|
|
40
|
+
"@gyoungwe/pi-knowledge",
|
|
41
|
+
"@gyoungwe/pi-research"
|
|
42
|
+
],
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@earendil-works/pi-coding-agent": ">=1.1.0 <2.0.0"
|
|
45
|
+
}
|
|
58
46
|
}
|
package/plugin.manifest.json
CHANGED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: research-workflow
|
|
3
|
-
description: "Bounded personal research workflow for Drone: local knowledge first, Web fallback, evidence verification, and parent-session-only knowledge writes."
|
|
4
|
-
alwaysWith: research
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Research Workflow
|
|
8
|
-
|
|
9
|
-
Use this skill for substantive research requests, literature discovery, source comparison, and evidence-backed technical investigation. This is not a second knowledge-base setup: initialization, read ordering and Wiki maintenance belong to `research-vault` and `/obsidian-setup`. Check that `research_loop` and the archive/verification tools are loaded before starting this project workflow; do not pretend unavailable tools exist.
|
|
10
|
-
|
|
11
|
-
1. Choose the task scope first: existing-literature consultation, discovery, deposition, planning or execution. Preserve the exact question. Use a persistent `research_loop(action=start)` when a tracked evidence run is needed; same-turn successful source reads may occur before or after start. Do not create execution/review milestones for a read-only consultation.
|
|
12
|
-
2. In desktop application mode, first use the current bounded global navigation and project context, read the relevant Wiki with `research_read_knowledge`, then search evidence with `research_search_knowledge`. Search the user's Zotero library through `zotero-literature` / `zotero-cli` (optional MCP `zotero` only if enabled). For newly acquired literature, deposit interpreted `Library/Papers` notes when writes are authorized; reuse existing notes without rewriting them for read-only tasks. Zotero hits are not Vault evidence receipts. Respect partial index coverage and pending Wiki reviews. In legacy project mode use the project Wiki and read-only Vault MCP. The host records successful local query/read receipts; do not manually repeat `record_local` to satisfy bookkeeping. A self-reported query alone is not proof of a successful tool call.
|
|
13
|
-
3. Use Web search only when local evidence is absent, stale, incomplete, or conflicting. The host records successful external lookup receipts. Read-only local reuse does not require a separate skip call; use `record_external` only when an explicit external-search decision needs recording.
|
|
14
|
-
4. Inspect original sources. A Wiki page, search snippet, failed MCP call, or `browser_required` result is not verified evidence and not a successful retrieval.
|
|
15
|
-
5. For newly acquired sources, archive authorized papers/manuals/software with traceable DOI/URL/version/license/hash. For papers call `research_archive_source category=papers doi=<doi>` without a url: the host resolves a legitimate open-access PDF (Europe PMC, PMC OA subset, Unpaywall, OpenAlex, Semantic Scholar, Crossref) and records every source it queried; `status=no_open_access` means no lawful copy exists — mark the paper abstract-only or ask the user to download it with their own access (`task_wait kind=download`, then `local_file` + `human_verified=true`). Never fetch from Sci-Hub or other pirate mirrors, and never invent a full-text URL. When the user wants a paper in Zotero, call `research_zotero_save` once per DOI (host-controlled: DOI dedup, native consent card unless the authorized plan lists the DOI as a `zotero_item` milestone, single write, DOI read-back), then deposit the `Library/Papers` note with the returned `zotero_key`. For read-only reuse, read the existing Library/Papers notes this turn, then call `research_verify_literature` for each DOI/key/path. The host matches the real read hash and current binding, rechecks identity, and records `sources_reused` without a new download or import. An identity check alone is not an original-source read. If a note is insufficient, state the limitation and seek bounded original-source evidence; do not fabricate reading.
|
|
16
|
-
6. After the bounded read/verification batch, call `research_loop(action=complete, claim_refs=[...])` once with explicit claim-to-paper/location/limitation references. The host closes the remaining stages serially. Do not manually walk inspect_sources/bind_claims/verify_archive/finalize or repeat retrieval merely to clear a warning. Reuse requires fresh current-turn receipts; changes to binding or content invalidate reuse. Plain research advice/read-only verification does not require task_plan or a human-review milestone; tasks with actual execution/writes still require the usual host consent.
|
|
17
|
-
7. Subagents may gather bounded evidence, may query the paired Obsidian knowledge base read-only when `subagentMcpPolicy=read-local`, and may write only inside the active run directory. The parent session alone owns persistent Obsidian/Vault deposition through controlled write tools.
|
|
18
|
-
8. After a completed run, reusable workflow successes or failures may be compiled into WikiSkill. WikiSkill patterns are operational experience, never scientific authority.
|
|
19
|
-
|
|
20
|
-
Do not weaken evidence standards to make an answer, Wiki page, or Skill look successful. Never invent citations, downloads, tool calls, archive state, or validation scores.
|
|
21
|
-
|
|
22
|
-
For application-mode Wiki maintenance, first read current source notes and the target Wiki, then stage `research_propose_wiki_update`. The user reviews the exact change with `/obsidian-review`. A staged or user-approved synthesis is not independently verified scientific evidence. Never bypass this through the old Wiki builder, raw MCP, shell, or `research_deposit_knowledge(type=wiki)`. Source checks and final-answer validation remain separate from Wiki write approval.
|
|
23
|
-
|
|
24
|
-
## User-facing delivery
|
|
25
|
-
|
|
26
|
-
### Answer shape (the user is a researcher, not an auditor)
|
|
27
|
-
|
|
28
|
-
Write the final answer for a domain scientist who wants a decision, not a compliance record. Evidence rules above are unchanged; this section only governs presentation.
|
|
29
|
-
|
|
30
|
-
1. **Lead with the answer.** The first 3–5 lines state the recommendation and the one or two facts that drive it (e.g. “用 DESeq2,设计公式 `~ hive + caste`;因为你的数据是 3 蜂箱 × 5 类 × 3 重复的完全交叉设计,而现有脚本先减蜂箱效应再检验是错误路线”). No preamble such as “研究完成”.
|
|
31
|
-
2. **Then what the user must decide**, as a short numbered list with a default for each item (“建议:装 R + Bioconductor”). Put this section second, not last — it is the only part that blocks progress.
|
|
32
|
-
3. **Then the reasoning**, in the user's language, plain paragraphs or short bullets. Explain *why* a choice matters for their result before naming the function; give at most one code identifier per sentence. Tables only for numbers the user will act on (QC outliers, sample counts), not to list everything measured.
|
|
33
|
-
4. **Data facts and QC**: report what changes a decision (outlier samples, library-size range, confounded groups). Skip measurements that merely confirm the data is normal unless asked.
|
|
34
|
-
5. **Problems in the user's existing work**: state each as “what it does → why it misleads → what to do instead”, ordered by impact. Do not enumerate cosmetic issues.
|
|
35
|
-
6. **Keep the answer readable and the sources traceable.** Keep exact Library/Papers citations beside the claims they support; do not replace them with a Wiki link or move all supporting citations away from the claims. Put run directories, archive hashes, `[[wiki links]]`, tool counts, failed download attempts and “not verified” bookkeeping at the end under a natural heading such as `参考资料与处理记录` (or `Sources & record`). A failed fetch is one clause (“Nygaard 2016 未能下载,未作为依据”), not a paragraph. Never put file hashes or run IDs in the body.
|
|
36
|
-
7. **Limitations are decision-relevant only.** One short paragraph: what the user should *not* conclude from this answer. Do not list every tool you did not run.
|
|
37
|
-
8. **Length**: a methods recommendation should fit on one screen (~600–900 Chinese characters / ~400–600 English words) before the `依据与记录` section. If the analysis genuinely needs more, offer the detail as a Show Me explainer or a saved run summary and link it rather than inlining.
|
|
38
|
-
9. **Tone**: second person, concrete, no hedging stacks. Say “不确定” once with the reason, not three synonyms. Avoid internal vocabulary (“宿主”“归档”“发布门禁”“证据回执”) in the body; if a host mechanism blocked something, say what the user can do (“既有文献的复用检查失败,暂未完成”;不要把程序错误归因为用户未确认或建议点击无关确认按钮).
|
|
39
|
-
|
|
40
|
-
10. **科研助手而不是执行清单**: When the user asks whether to continue or what to do next, begin with the scientific conclusion and evidence level. Give one recommended sequence and its rationale. Do not begin with “写入笔记”“绑定 claims”“生成 Wiki” or another storage operation; put those actions after the scientific answer under `依据与记录`, if they matter at all. Translate “已读/未读/未核验” into what the evidence can and cannot support, and state which primary evidence would change the conclusion.
|
|
41
|
-
|
|
42
|
-
A useful self-check before `research_check_answer`: could the user act on the first screen alone? If not, restructure rather than add.
|
|
43
|
-
|
|
44
|
-
### Interruption budget (ask once, then decide)
|
|
45
|
-
|
|
46
|
-
The user wants to be involved at most once per task. Treat every question to the user as expensive:
|
|
47
|
-
|
|
48
|
-
1. **Front-load decisions.** Before the first tool call that needs user input, list *every* choice you can already foresee for the whole task in one message (analysis engine, which samples to include, batch vs. block, output format, whether to install software). Each item carries a recommended default in one line. Do not ask them one at a time across turns.
|
|
49
|
-
2. **Mid-task: decide, don't ask.** If a new choice appears after the user has answered (or after they approved a permission with “本次任务全部允许”), take the most defensible default, continue, and record it. Only stop for genuinely irreversible or destructive actions the user did not foresee (deleting data, overwriting their own files, spending money).
|
|
50
|
-
3. **Report decisions made on their behalf** in a short, natural paragraph or list when they matter: “我按 X 处理了;如需改为 Y,回复一句即可”. Do not force a fixed heading or repeat this section when there were no meaningful decisions.
|
|
51
|
-
4. **Never re-ask** something already answered in this session or recorded in the run; reuse the answer.
|
|
52
|
-
5. **Budget/stage checkpoints from the host** are not questions to relay verbatim. Finish the answer with what you already have, then tell the user in one sentence how to let the task continue.
|
|
53
|
-
|
|
54
|
-
Load the relevant delivery sections of `research-vault` for a paper/software/manual task. “Download the manual” includes the version-specific CLI reference, arguments, input/output and runnable example explanations, not just the homepage or a bibliographic entry. Capture substantive paper methods/claims and software principles/usage in reusable source-grounded notes. A generated run summary is an operational record; its successful save is not scientific verification.
|
|
55
|
-
|
|
56
|
-
When the user requests an explainer and writes are authorized, use the loaded show-me skill after source reading for a focused explainer, linked in the normal final text answer. Do not create presentation artifacts for plain read-only planning. For software, distinguish documented performance from local measured tests (or explicitly “not tested”); for research, explain the main viewpoint, methods, evidence and limitations. Never substitute the UI progress status for delivery or treat file download as comprehension.
|
|
57
|
-
|
|
58
|
-
After `research_summarize_run` succeeds in application mode, the host automatically stages one shared topic Wiki candidate when the summary is substantial and at least one current-version non-Wiki evidence note was actually read this turn. The candidate is generated from the saved summary, stored outside the live Vault, and remains unverified until the user reviews it. Do not create a duplicate proposal unless the host reports that automatic staging was skipped or failed; if an existing topic requires a fresh read, read it and then propose the correction explicitly.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
## Show Me in the knowledge base
|
|
62
|
-
|
|
63
|
-
After generating a source-grounded Show Me HTML/Markdown file under the configured results root, call `research_archive_explainer` with the active research run `metadata.topic_id` (reuse it across rounds), title, short summary, and 1–12 underlying evidence note paths that were actually read this turn. The host copies the visual artifact into `Attachments/Explainers/<topic-id>/`, maintains `Library/Explainers/<topic-id>.md` as the searchable latest/history pointer, and preserves human review text. Explainers are presentation-only: they may help a human navigate and understand a topic, but they are excluded from evidence receipts, automatic Wiki source selection, and scientific verification. Never cite an older explainer instead of the paper/software/manual sources it summarizes.
|
|
64
|
-
|
|
65
|
-
## Knowledge-service specialists
|
|
66
|
-
|
|
67
|
-
The desktop host may automatically dispatch `knowledge-navigator` for knowledge-oriented requests, and `knowledge-evidence-curator` for comparisons with multiple located sources. After a successful parent research summary it may invoke `knowledge-wiki-editor` and `knowledge-explainer`. These are bounded isolated model calls, not four agents for every chat message. The application has automatic/manual/off modes and a read-local permission ceiling; respect disabled modes and do not bypass them with generic subagents.
|
|
68
|
-
|
|
69
|
-
Each child receives only its current task, bounded selected notes and (for the explainer only) the actually loaded show-me skill. No parent transcript, general filesystem/shell tools, raw MCP writes, network-fetch capability, recursive delegation or approval tool is available. Parent handoffs are compact unverified summaries with current source ranges. They do not mint parent read/search receipts: read the originals needed for the final answer through native tools. A source record is not full-paper/manual comprehension.
|
|
70
|
-
|
|
71
|
-
Do not duplicate the host's post-summary Show Me or Wiki work in automatic mode. Use `research_delegate_knowledge` for explicit scoped tasks when appropriate; Wiki delegation requires a target and parent-read sources, and explainer delegation requires an existing research run and stable topic id. The child submits content, while the parent host stages a Wiki candidate or saves an explainer only after checking policy, source versions and path constraints. Actual Wiki approval remains exclusively human. Presentation artifacts remain outside the evidence layer.
|
|
72
|
-
|
|
73
|
-
No raw child transcript or model reasoning is returned to the parent. Longer Wiki/HTML content remains on the host and is surfaced through a candidate/artifact link; visible progress includes role, model, observed activity, token usage and failures. At most four role calls per user turn (one per role), two concurrent knowledge specialists, three total native children with lower per-project ceilings respected, 120-second per-call deadlines and no unbounded retries. New user turns and cancellation invalidate pending work. Failures or missing show-me must be stated, not reported as completed output.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## Research design and evidence boundaries (required)
|
|
77
|
-
|
|
78
|
-
For read-only planning or reuse, do not create task plans, human-review milestones, explainers or child agents merely to satisfy workflow bookkeeping. Read existing source notes and verify identities in parallel where independent; a tracked run may start before or after those reads in the same turn. The host retains successful receipts. Complete once with explicit claim bindings; do not manually backfill local/external/inspection stages or re-import papers to clear a gate. A run writes operational metadata even if the literature/Vault task is read-only; do not claim absolutely no files were written.
|
|
79
|
-
|
|
80
|
-
Keep four dimensions separate: bibliographic identity, acquisition/attachments, actual reading scope, and claim support. DOI/hash checks establish identity/version, not scientific validation. This-turn note reuse is not this-turn HTML/PDF reading. State historical original-reading locations as historical, and cite the exact note beside the supported claim. A downloaded paper is not automatically read or evidence for a claim. Report inaccessible OA fulltext honestly; preserve metadata-only states and human notes.
|
|
81
|
-
|
|
82
|
-
Research plans must start from a testable question, not a software list. Identify sampling units, biological replicates, comparison groups, data/annotation quality, method assumptions, confounders, alternative explanations and the experiments needed for causal claims. Distinguish proposed, executed and QC-passed analyses. Mark sample counts, thresholds and parameters as source-backed, user-constrained or provisional; never invent a universal minimum.
|
|
83
|
-
|
|
84
|
-
Before final delivery, check:
|
|
85
|
-
- Ligands/receptors, DNA-binding TFs, cofactors and effectors are different categories. Wg/Dpp/Hh are not DNA-binding motif models. Motif hits are not occupancy or causality.
|
|
86
|
-
- A specific tool's protein-input requirement is not a universal requirement of all homology inference. Identify the relevant software/version.
|
|
87
|
-
- Species groups must use compatible levels or explicitly crossed factors: Neuroptera belong within holometabolous insects, not a mutually exclusive third group alongside hemi-/holometaboly.
|
|
88
|
-
- Single-species/tissue/stage results are evidence for the tested conditions; broader conservation remains a hypothesis. Orthology, expression correlation, perturbation and direct binding support different claims.
|
|
89
|
-
- Apparent gene absence/copy differences require checks for assembly/annotation/isoform artifacts; comparative tests must consider phylogenetic non-independence. Cross-species expression requires comparable tissues/stages.
|
|
90
|
-
- No hits, non-significance and no phenotype do not prove absence/no function. A literature-gap claim must state search scope/date, or be qualified as not established.
|
|
91
|
-
|
|
92
|
-
These are reasoning checks, not a claim that the host has scientifically validated the answer. If a method layer lacks appropriate sources, mark it provisional, name the missing original methods/version documentation, and offer a bounded next step with a concrete deliverable (for example, “可继续补检 dN/dS 与 CAFE 的方法原文和当前版本手册,整理适用前提、输入、参数依据与局限”). Use external read-only retrieval when it is already within the requested scope; otherwise include this option with the other end-of-answer decisions. Keep unsourced parameters provisional and preserve explicit local-only or no-write constraints.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
## Structured claims and interrupted-operation recovery
|
|
96
|
-
|
|
97
|
-
Prefer `research_loop(action=complete, claim_bindings=[...])`: each binding includes claim, relationship (direct/indirect/hypothesis/unsupported), organism and method where applicable, limitations, and source entries with path/start_line/end_line/verbatim quote. Use the actually read note lines, not guessed original PDF lines. `original_location` is a historical locator only; it does not claim this-turn original reading. The host checks identity, current hash, read range and quote; support relationship remains model-asserted/unreviewed. Legacy claim_refs carry an unstructured warning, not equivalent verification.
|
|
98
|
-
|
|
99
|
-
When calling `research_summarize_run`, carry the evidence-backed observations into its optional `claims` array so topic memory can compare this run with prior knowledge. For each substantive claim provide `claim`, `subject`, `predicate`, `sourcePath`, `sourceHash` and `relation` (`observation`, `interpretation`, or `hypothesis`), plus `value`, `organism`, `tissue`, `stage`, `method`, and `location` when they affect interpretation. Use the exact Vault note hash and path returned by a successful read. Keep different conditions as separate claims; do not turn a summary sentence, search snippet, or model inference without a read receipt into a claim. If a run has no substantive evidence-backed claims, omit `claims` rather than filling it with placeholders.
|
|
100
|
-
|
|
101
|
-
If deposition fails or its response is uncertain, call `research_reconcile_literature` with run_dir/DOI/key/note path BEFORE another write. Its persistent per-DOI log reports destinations separately. Reuse verified destinations, preserve human notes, and only complete a missing side with the user's existing write authorization and controlled tools. Unavailable is not absent; identity conflicts require review. Reconciliation itself makes zero library writes; it is not automatic import permission or scientific validation.
|
|
102
|
-
|
|
103
|
-
The UI recovery action continues the existing unfinished answer with a host checkpoint and read-only tools. It does not send the original user prompt again or automatically retry writes. If the process restarted, old receipts may need fresh verification; do not relabel historical evidence as current. Report a remaining execution/deposition failure explicitly instead of pretending read-only answer recovery completed it.
|