psyclaw 0.28.3 → 0.29.2
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 +12 -11
- package/agents/recommended/catalog.json +2 -2
- package/dist/src/adapters/pi/extension.js +310 -256
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/analysis/hooks.js +1 -1
- package/dist/src/analysis/hooks.js.map +1 -1
- package/dist/src/analysis/plan.d.ts +82 -0
- package/dist/src/analysis/plan.js +246 -0
- package/dist/src/analysis/plan.js.map +1 -0
- package/dist/src/analysis/stats-router.d.ts +13 -0
- package/dist/src/analysis/stats-router.js +44 -0
- package/dist/src/analysis/stats-router.js.map +1 -0
- package/dist/src/ars/academic-router.d.ts +33 -0
- package/dist/src/ars/academic-router.js +204 -0
- package/dist/src/ars/academic-router.js.map +1 -0
- package/dist/src/ars/doctor.d.ts +27 -0
- package/dist/src/ars/doctor.js +121 -0
- package/dist/src/ars/doctor.js.map +1 -0
- package/dist/src/ars/mode-editor.d.ts +14 -7
- package/dist/src/ars/mode-editor.js +39 -23
- package/dist/src/ars/mode-editor.js.map +1 -1
- package/dist/src/ars/profile.d.ts +10 -0
- package/dist/src/ars/profile.js +15 -2
- package/dist/src/ars/profile.js.map +1 -1
- package/dist/src/branding.js +15 -16
- package/dist/src/branding.js.map +1 -1
- package/dist/src/cli.js +1 -8
- package/dist/src/cli.js.map +1 -1
- package/dist/src/index.d.ts +6 -1
- package/dist/src/index.js +6 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/panel/server.js +1 -1
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/project/approvals.d.ts +4 -3
- package/dist/src/project/approvals.js +4 -3
- package/dist/src/project/approvals.js.map +1 -1
- package/dist/src/project/bootstrap.d.ts +7 -2
- package/dist/src/project/bootstrap.js +14 -13
- package/dist/src/project/bootstrap.js.map +1 -1
- package/dist/src/project/paths.d.ts +10 -0
- package/dist/src/project/paths.js +20 -3
- package/dist/src/project/paths.js.map +1 -1
- package/dist/src/project/workspace.d.ts +14 -0
- package/dist/src/project/workspace.js +82 -0
- package/dist/src/project/workspace.js.map +1 -0
- package/dist/src/session/modes.d.ts +10 -0
- package/dist/src/session/modes.js +57 -0
- package/dist/src/session/modes.js.map +1 -0
- package/dist/src/skills/recommended.js +1 -1
- package/dist/src/skills/recommended.js.map +1 -1
- package/dist/src/style/cli-ui.js +3 -3
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/verify/checklist.d.ts +20 -0
- package/dist/src/verify/checklist.js +71 -0
- package/dist/src/verify/checklist.js.map +1 -0
- package/package.json +2 -1
- package/scripts/rebrand-pi.mjs +2 -2
- package/skills/core/academic-grill/SKILL.md +1 -1
- package/skills/core/analysis-plan/SKILL.md +29 -0
- package/skills/core/manifest.json +3 -3
- package/vendor/ars/pi/wrapper.js +14 -5
- package/vendor/ars/pi/wrapper.test.mjs +10 -0
- package/dist/src/research/brief.d.ts +0 -11
- package/dist/src/research/brief.js +0 -81
- package/dist/src/research/brief.js.map +0 -1
- package/skills/core/research-brief/SKILL.md +0 -17
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type AnalysisPlanContract } from "./hooks.js";
|
|
2
|
+
export declare const ANALYSIS_PLAN_SCHEMA: "psyclaw/analysis-plan/v1";
|
|
3
|
+
export declare const ANALYSIS_PLAN_ACTIVE: "analysis/plans/active.json";
|
|
4
|
+
export type AnalysisPlanStatus = "clarifying" | "drafting" | "awaiting-confirm" | "reviewing" | "ready" | "running" | "deferred" | "completed" | "blocked";
|
|
5
|
+
export type AnalysisPlanStage = "clarify-eda" | "propose" | "confirm" | "review" | "execute" | "report-checks" | "handoff";
|
|
6
|
+
export type AnalysisExecutionBackend = "local-script" | "mcp" | "undecided";
|
|
7
|
+
export interface AnalysisPlanEdaNote {
|
|
8
|
+
at: string;
|
|
9
|
+
summary: string;
|
|
10
|
+
paths?: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface AnalysisPlanRecord extends AnalysisPlanContract {
|
|
13
|
+
schemaVersion: typeof ANALYSIS_PLAN_SCHEMA;
|
|
14
|
+
id: string;
|
|
15
|
+
status: AnalysisPlanStatus;
|
|
16
|
+
stage: AnalysisPlanStage;
|
|
17
|
+
goal: string;
|
|
18
|
+
dataPaths: string[];
|
|
19
|
+
questions: string[];
|
|
20
|
+
edaNotes: AnalysisPlanEdaNote[];
|
|
21
|
+
proposedMethods: string[];
|
|
22
|
+
confirmedMethod?: string;
|
|
23
|
+
executionBackend: AnalysisExecutionBackend;
|
|
24
|
+
mcpServer?: string;
|
|
25
|
+
scriptEntrypoint?: string;
|
|
26
|
+
reviewFindings: string[];
|
|
27
|
+
runPreference: "unset" | "now" | "later";
|
|
28
|
+
createdAt: string;
|
|
29
|
+
updatedAt: string;
|
|
30
|
+
notes?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function createAnalysisPlan(input: {
|
|
33
|
+
goal: string;
|
|
34
|
+
dataPaths?: string[];
|
|
35
|
+
confirmatory?: boolean;
|
|
36
|
+
now?: string;
|
|
37
|
+
}): AnalysisPlanRecord;
|
|
38
|
+
export declare function analysisPlansDir(root: string): Promise<string>;
|
|
39
|
+
export declare function writeAnalysisPlan(root: string, plan: AnalysisPlanRecord): Promise<AnalysisPlanRecord>;
|
|
40
|
+
export declare function readAnalysisPlan(root: string, id: string): Promise<AnalysisPlanRecord | null>;
|
|
41
|
+
export declare function readActiveAnalysisPlan(root: string): Promise<AnalysisPlanRecord | null>;
|
|
42
|
+
export declare function listAnalysisPlans(root: string): Promise<string[]>;
|
|
43
|
+
export declare function advanceAnalysisPlan(plan: AnalysisPlanRecord, action: {
|
|
44
|
+
type: "add-question";
|
|
45
|
+
question: string;
|
|
46
|
+
} | {
|
|
47
|
+
type: "add-eda";
|
|
48
|
+
summary: string;
|
|
49
|
+
paths?: string[];
|
|
50
|
+
} | {
|
|
51
|
+
type: "draft";
|
|
52
|
+
primaryOutcome?: string;
|
|
53
|
+
primaryAnalysis?: string;
|
|
54
|
+
exploratoryAnalyses?: string[];
|
|
55
|
+
proposedMethods?: string[];
|
|
56
|
+
missingDataPlan?: string;
|
|
57
|
+
multiplicityPlan?: string;
|
|
58
|
+
exclusionCriteria?: string;
|
|
59
|
+
} | {
|
|
60
|
+
type: "confirm";
|
|
61
|
+
method: string;
|
|
62
|
+
backend?: AnalysisExecutionBackend;
|
|
63
|
+
mcpServer?: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: "review";
|
|
66
|
+
} | {
|
|
67
|
+
type: "ready";
|
|
68
|
+
} | {
|
|
69
|
+
type: "run-now";
|
|
70
|
+
} | {
|
|
71
|
+
type: "defer";
|
|
72
|
+
} | {
|
|
73
|
+
type: "complete";
|
|
74
|
+
scriptEntrypoint?: string;
|
|
75
|
+
} | {
|
|
76
|
+
type: "block";
|
|
77
|
+
reason: string;
|
|
78
|
+
}): AnalysisPlanRecord;
|
|
79
|
+
export declare function renderAnalysisPlanMarkdown(plan: AnalysisPlanRecord): string;
|
|
80
|
+
export declare function formatAnalysisPlanStatus(plan: AnalysisPlanRecord): string;
|
|
81
|
+
/** Seed HANDOFF fields from a completed/ready plan without wiping human edits wholesale when stubby. */
|
|
82
|
+
export declare function syncHandoffFromAnalysisPlan(root: string, plan: AnalysisPlanRecord): Promise<string>;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { atomicWriteFile } from "../project/jsonl.js";
|
|
4
|
+
import { assertSafeProjectPath, projectPaths } from "../project/paths.js";
|
|
5
|
+
import { validateAnalysisPlan } from "./hooks.js";
|
|
6
|
+
export const ANALYSIS_PLAN_SCHEMA = "psyclaw/analysis-plan/v1";
|
|
7
|
+
export const ANALYSIS_PLAN_ACTIVE = "analysis/plans/active.json";
|
|
8
|
+
const STATUS_STAGE = {
|
|
9
|
+
clarifying: "clarify-eda",
|
|
10
|
+
drafting: "propose",
|
|
11
|
+
"awaiting-confirm": "confirm",
|
|
12
|
+
reviewing: "review",
|
|
13
|
+
ready: "execute",
|
|
14
|
+
running: "execute",
|
|
15
|
+
deferred: "execute",
|
|
16
|
+
completed: "handoff",
|
|
17
|
+
blocked: "review",
|
|
18
|
+
};
|
|
19
|
+
function nowIso() {
|
|
20
|
+
return new Date().toISOString();
|
|
21
|
+
}
|
|
22
|
+
function planId(now = Date.now()) {
|
|
23
|
+
return `ap_${now}`;
|
|
24
|
+
}
|
|
25
|
+
export function createAnalysisPlan(input) {
|
|
26
|
+
const createdAt = input.now ?? nowIso();
|
|
27
|
+
return {
|
|
28
|
+
schemaVersion: ANALYSIS_PLAN_SCHEMA,
|
|
29
|
+
id: planId(Date.parse(createdAt) || Date.now()),
|
|
30
|
+
status: "clarifying",
|
|
31
|
+
stage: "clarify-eda",
|
|
32
|
+
goal: input.goal.trim() || "未命名分析目标",
|
|
33
|
+
confirmatory: input.confirmatory === true,
|
|
34
|
+
exploratoryAnalyses: input.confirmatory === true ? [] : ["待澄清后声明"],
|
|
35
|
+
dataPaths: [...(input.dataPaths ?? [])],
|
|
36
|
+
questions: [],
|
|
37
|
+
edaNotes: [],
|
|
38
|
+
proposedMethods: [],
|
|
39
|
+
executionBackend: "local-script",
|
|
40
|
+
reviewFindings: [],
|
|
41
|
+
runPreference: "unset",
|
|
42
|
+
createdAt,
|
|
43
|
+
updatedAt: createdAt,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export async function analysisPlansDir(root) {
|
|
47
|
+
const dir = await assertSafeProjectPath(root, "analysis/plans");
|
|
48
|
+
await mkdir(dir, { recursive: true });
|
|
49
|
+
return dir;
|
|
50
|
+
}
|
|
51
|
+
export async function writeAnalysisPlan(root, plan) {
|
|
52
|
+
const dir = await analysisPlansDir(root);
|
|
53
|
+
const updated = { ...plan, stage: STATUS_STAGE[plan.status], updatedAt: nowIso() };
|
|
54
|
+
const file = join(dir, `${updated.id}.json`);
|
|
55
|
+
await atomicWriteFile(file, `${JSON.stringify(updated, null, 2)}\n`);
|
|
56
|
+
await atomicWriteFile(join(dir, "active.json"), `${JSON.stringify({ schemaVersion: "psyclaw/analysis-plan-active/v1", planId: updated.id, updatedAt: updated.updatedAt }, null, 2)}\n`);
|
|
57
|
+
await atomicWriteFile(join(dir, `${updated.id}.md`), renderAnalysisPlanMarkdown(updated));
|
|
58
|
+
return updated;
|
|
59
|
+
}
|
|
60
|
+
export async function readAnalysisPlan(root, id) {
|
|
61
|
+
try {
|
|
62
|
+
const path = await assertSafeProjectPath(root, `analysis/plans/${id}.json`);
|
|
63
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
64
|
+
if (value.schemaVersion !== ANALYSIS_PLAN_SCHEMA || typeof value.id !== "string")
|
|
65
|
+
return null;
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function readActiveAnalysisPlan(root) {
|
|
73
|
+
try {
|
|
74
|
+
const activePath = await assertSafeProjectPath(root, ANALYSIS_PLAN_ACTIVE);
|
|
75
|
+
const active = JSON.parse(await readFile(activePath, "utf8"));
|
|
76
|
+
if (!active.planId)
|
|
77
|
+
return null;
|
|
78
|
+
return readAnalysisPlan(root, active.planId);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function listAnalysisPlans(root) {
|
|
85
|
+
try {
|
|
86
|
+
const dir = await analysisPlansDir(root);
|
|
87
|
+
const names = await readdir(dir);
|
|
88
|
+
return names.filter((name) => /^ap_\d+\.json$/.test(name)).map((name) => name.replace(/\.json$/, "")).sort();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function advanceAnalysisPlan(plan, action) {
|
|
95
|
+
const next = { ...plan, updatedAt: nowIso() };
|
|
96
|
+
switch (action.type) {
|
|
97
|
+
case "add-question":
|
|
98
|
+
next.questions = [...plan.questions, action.question.trim()].filter(Boolean);
|
|
99
|
+
next.status = "clarifying";
|
|
100
|
+
break;
|
|
101
|
+
case "add-eda":
|
|
102
|
+
next.edaNotes = [...plan.edaNotes, { at: nowIso(), summary: action.summary.trim(), ...(action.paths ? { paths: action.paths } : {}) }];
|
|
103
|
+
next.status = "clarifying";
|
|
104
|
+
break;
|
|
105
|
+
case "draft":
|
|
106
|
+
if (action.primaryOutcome !== undefined)
|
|
107
|
+
next.primaryOutcome = action.primaryOutcome;
|
|
108
|
+
if (action.primaryAnalysis !== undefined)
|
|
109
|
+
next.primaryAnalysis = action.primaryAnalysis;
|
|
110
|
+
if (action.exploratoryAnalyses !== undefined)
|
|
111
|
+
next.exploratoryAnalyses = action.exploratoryAnalyses;
|
|
112
|
+
if (action.proposedMethods !== undefined)
|
|
113
|
+
next.proposedMethods = action.proposedMethods;
|
|
114
|
+
if (action.missingDataPlan !== undefined)
|
|
115
|
+
next.missingDataPlan = action.missingDataPlan;
|
|
116
|
+
if (action.multiplicityPlan !== undefined)
|
|
117
|
+
next.multiplicityPlan = action.multiplicityPlan;
|
|
118
|
+
if (action.exclusionCriteria !== undefined)
|
|
119
|
+
next.exclusionCriteria = action.exclusionCriteria;
|
|
120
|
+
next.status = "awaiting-confirm";
|
|
121
|
+
break;
|
|
122
|
+
case "confirm":
|
|
123
|
+
next.confirmedMethod = action.method.trim();
|
|
124
|
+
next.primaryAnalysis = action.method.trim();
|
|
125
|
+
next.executionBackend = action.backend ?? "local-script";
|
|
126
|
+
if (action.mcpServer)
|
|
127
|
+
next.mcpServer = action.mcpServer;
|
|
128
|
+
next.status = "reviewing";
|
|
129
|
+
break;
|
|
130
|
+
case "review": {
|
|
131
|
+
const result = validateAnalysisPlan(next);
|
|
132
|
+
next.reviewFindings = result.findings.map((finding) => `${finding.severity}: ${finding.message}`);
|
|
133
|
+
next.status = result.findings.some((finding) => finding.severity === "block") ? "blocked" : "ready";
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case "ready":
|
|
137
|
+
next.status = "ready";
|
|
138
|
+
break;
|
|
139
|
+
case "run-now":
|
|
140
|
+
next.runPreference = "now";
|
|
141
|
+
next.status = "running";
|
|
142
|
+
break;
|
|
143
|
+
case "defer":
|
|
144
|
+
next.runPreference = "later";
|
|
145
|
+
next.status = "deferred";
|
|
146
|
+
break;
|
|
147
|
+
case "complete":
|
|
148
|
+
if (action.scriptEntrypoint)
|
|
149
|
+
next.scriptEntrypoint = action.scriptEntrypoint;
|
|
150
|
+
next.status = "completed";
|
|
151
|
+
break;
|
|
152
|
+
case "block":
|
|
153
|
+
next.reviewFindings = [...next.reviewFindings, `block: ${action.reason}`];
|
|
154
|
+
next.status = "blocked";
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
next.stage = STATUS_STAGE[next.status];
|
|
158
|
+
return next;
|
|
159
|
+
}
|
|
160
|
+
export function renderAnalysisPlanMarkdown(plan) {
|
|
161
|
+
const lines = [
|
|
162
|
+
`# Analysis plan \`${plan.id}\``,
|
|
163
|
+
"",
|
|
164
|
+
`- Status: **${plan.status}** (stage: ${plan.stage})`,
|
|
165
|
+
`- Goal: ${plan.goal}`,
|
|
166
|
+
`- Confirmatory: ${plan.confirmatory ? "yes" : "no (exploratory OK if disclosed)"}`,
|
|
167
|
+
`- Execution: ${plan.executionBackend}${plan.mcpServer ? ` (${plan.mcpServer})` : ""}`,
|
|
168
|
+
`- Run preference: ${plan.runPreference}`,
|
|
169
|
+
"",
|
|
170
|
+
"## Data",
|
|
171
|
+
"",
|
|
172
|
+
...(plan.dataPaths.length > 0 ? plan.dataPaths.map((path) => `- ${path}`) : ["- (not set)"]),
|
|
173
|
+
"",
|
|
174
|
+
"## Clarifying questions",
|
|
175
|
+
"",
|
|
176
|
+
...(plan.questions.length > 0 ? plan.questions.map((q, i) => `${i + 1}. ${q}`) : ["- (none yet)"]),
|
|
177
|
+
"",
|
|
178
|
+
"## EDA notes",
|
|
179
|
+
"",
|
|
180
|
+
...(plan.edaNotes.length > 0
|
|
181
|
+
? plan.edaNotes.map((note) => `- ${note.at}: ${note.summary}${note.paths?.length ? ` (${note.paths.join(", ")})` : ""}`)
|
|
182
|
+
: ["- (none yet)"]),
|
|
183
|
+
"",
|
|
184
|
+
"## Proposal",
|
|
185
|
+
"",
|
|
186
|
+
`- Primary outcome: ${plan.primaryOutcome ?? "(missing)"}`,
|
|
187
|
+
`- Primary analysis: ${plan.primaryAnalysis ?? "(missing)"}`,
|
|
188
|
+
`- Confirmed method: ${plan.confirmedMethod ?? "(not confirmed)"}`,
|
|
189
|
+
`- Proposed methods: ${plan.proposedMethods.join("; ") || "(none)"}`,
|
|
190
|
+
`- Exploratory: ${(plan.exploratoryAnalyses ?? []).join("; ") || "(none)"}`,
|
|
191
|
+
`- Missing data: ${plan.missingDataPlan ?? "(missing)"}`,
|
|
192
|
+
`- Multiplicity: ${plan.multiplicityPlan ?? "(missing)"}`,
|
|
193
|
+
`- Exclusion: ${plan.exclusionCriteria ?? "(missing)"}`,
|
|
194
|
+
"",
|
|
195
|
+
"## Review",
|
|
196
|
+
"",
|
|
197
|
+
...(plan.reviewFindings.length > 0 ? plan.reviewFindings.map((item) => `- ${item}`) : ["- (not reviewed)"]),
|
|
198
|
+
"",
|
|
199
|
+
"## Execution",
|
|
200
|
+
"",
|
|
201
|
+
`- Script entrypoint: ${plan.scriptEntrypoint ?? "analysis/scripts/run_all.py (expected)"}`,
|
|
202
|
+
"- Default: write local reproducible scripts; MCP only for special backends or explicit request.",
|
|
203
|
+
"",
|
|
204
|
+
"## Next",
|
|
205
|
+
"",
|
|
206
|
+
plan.status === "ready" || plan.status === "deferred"
|
|
207
|
+
? "- Choose `/plan run` (now) or `/plan defer` (later), then execute."
|
|
208
|
+
: plan.status === "completed"
|
|
209
|
+
? "- Update `analysis/HANDOFF.md` before switching to academic."
|
|
210
|
+
: "- Continue the current stage; do not jump to academic/ARS.",
|
|
211
|
+
"",
|
|
212
|
+
];
|
|
213
|
+
return lines.join("\n");
|
|
214
|
+
}
|
|
215
|
+
export function formatAnalysisPlanStatus(plan) {
|
|
216
|
+
return [
|
|
217
|
+
`分析 Plan \`${plan.id}\` · ${plan.status}/${plan.stage}`,
|
|
218
|
+
`目标:${plan.goal}`,
|
|
219
|
+
`主分析:${plan.confirmedMethod ?? plan.primaryAnalysis ?? "(未确认)"}`,
|
|
220
|
+
`后端:${plan.executionBackend}${plan.mcpServer ? `/${plan.mcpServer}` : ""} · 执行偏好:${plan.runPreference}`,
|
|
221
|
+
`文件:analysis/plans/${plan.id}.md`,
|
|
222
|
+
plan.reviewFindings.length > 0 ? `审核:${plan.reviewFindings.join(";")}` : "审核:尚未完成或无发现",
|
|
223
|
+
].join("\n");
|
|
224
|
+
}
|
|
225
|
+
/** Seed HANDOFF fields from a completed/ready plan without wiping human edits wholesale when stubby. */
|
|
226
|
+
export async function syncHandoffFromAnalysisPlan(root, plan) {
|
|
227
|
+
const path = projectPaths(root).analysisHandoff;
|
|
228
|
+
const block = [
|
|
229
|
+
`# Analysis → Academic handoff`,
|
|
230
|
+
"",
|
|
231
|
+
`- Status: ${plan.status === "completed" ? "ready-for-academic" : "draft"}`,
|
|
232
|
+
`- Plan id: ${plan.id}`,
|
|
233
|
+
`- Question / design: ${plan.goal}`,
|
|
234
|
+
`- Primary analysis: ${plan.confirmedMethod ?? plan.primaryAnalysis ?? ""}`,
|
|
235
|
+
`- Primary outcome: ${plan.primaryOutcome ?? ""}`,
|
|
236
|
+
`- Primary results paths: ${plan.scriptEntrypoint ?? "analysis/results/"}`,
|
|
237
|
+
`- Key numbers (N, effects): (fill after execution)`,
|
|
238
|
+
`- Limits / unverified items: ${(plan.reviewFindings.concat(plan.exploratoryAnalyses ?? [])).join("; ") || "none listed"}`,
|
|
239
|
+
`- Ready for academic: ${plan.status === "completed" ? "yes-if-results-present" : "no"}`,
|
|
240
|
+
"",
|
|
241
|
+
].join("\n");
|
|
242
|
+
await mkdir(projectPaths(root).analysis, { recursive: true });
|
|
243
|
+
await atomicWriteFile(path, block);
|
|
244
|
+
return "analysis/HANDOFF.md";
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/analysis/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis-mode stats intent router.
|
|
3
|
+
* When matched in analysis mode, soft-takeover into the analysis-plan skill.
|
|
4
|
+
* Does not compete with academic ARS soft-routing.
|
|
5
|
+
*/
|
|
6
|
+
export interface StatsIntentMatch {
|
|
7
|
+
kind: "stats-analysis";
|
|
8
|
+
reason: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function resolveStatsIntent(text: string): StatsIntentMatch | null;
|
|
11
|
+
export declare function formatAnalysisPlanTakeover(userText: string): string;
|
|
12
|
+
/** System-prompt contract for analysis sticky mode. */
|
|
13
|
+
export declare function analysisSoftRoutePrompt(): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis-mode stats intent router.
|
|
3
|
+
* When matched in analysis mode, soft-takeover into the analysis-plan skill.
|
|
4
|
+
* Does not compete with academic ARS soft-routing.
|
|
5
|
+
*/
|
|
6
|
+
const STATS_INTENT = /统计|分析数据|数据分析|跑(一下)?(检验|回归|方差|anova|相关)|t\s*检验|方差分析|回归分析|中介|调节|SEM|因子(分析)?|生存分析|功效|样本量|描述统计|探索性|EDA|analysis plan|统计方案|帮我分析|看一下(这个)?数据|dataset|csv|\.sav\b|独立样本|配对样本|重复测量|混合设计|多层(模型|线性)|meta[- ]?analysis|元分析/i;
|
|
7
|
+
const EXPLICIT_SKIP = /^\/(?:skill:|plan\b|ars(?:-|\b)|init\b|verify\b|grill\b|review\b|loop\b|mcp\b|agents\b|provider\b|panel\b|help\b)/i;
|
|
8
|
+
/** Academic writing intents should not steal analysis-plan takeover. */
|
|
9
|
+
const ACADEMIC_DOMINANT = /写论文|成稿|审稿|文献综述|润色终稿|\/ars-|academic-paper|同行评审/i;
|
|
10
|
+
export function resolveStatsIntent(text) {
|
|
11
|
+
const trimmed = text.trim();
|
|
12
|
+
if (!trimmed || EXPLICIT_SKIP.test(trimmed))
|
|
13
|
+
return null;
|
|
14
|
+
if (ACADEMIC_DOMINANT.test(trimmed) && !/先分析|先跑|数据分析|统计方案/.test(trimmed))
|
|
15
|
+
return null;
|
|
16
|
+
if (!STATS_INTENT.test(trimmed))
|
|
17
|
+
return null;
|
|
18
|
+
return { kind: "stats-analysis", reason: "statistical / data-analysis intent" };
|
|
19
|
+
}
|
|
20
|
+
export function formatAnalysisPlanTakeover(userText) {
|
|
21
|
+
return [
|
|
22
|
+
"/skill:analysis-plan",
|
|
23
|
+
"",
|
|
24
|
+
"Analysis-plan soft takeover. Follow the analysis-plan skill stages now; do not ask the user to retype /skill:analysis-plan.",
|
|
25
|
+
"Do not start academic/ARS writing. Do not invent numerical results.",
|
|
26
|
+
"Default execution backend: write reproducible scripts under analysis/scripts/ using mature libraries (pandas/pingouin/statsmodels/scipy or R equivalents).",
|
|
27
|
+
"Use MCP only when the user needs a special backend (SPSS/Mplus/MNE/Stata) or explicitly asks.",
|
|
28
|
+
"Persist structured state with /plan (new|status|confirm|review|run|defer|handoff); soft confirm ≠ ARS checkpoint ≠ awaiting-human.",
|
|
29
|
+
"User request:",
|
|
30
|
+
userText.trim(),
|
|
31
|
+
].join("\n");
|
|
32
|
+
}
|
|
33
|
+
/** System-prompt contract for analysis sticky mode. */
|
|
34
|
+
export function analysisSoftRoutePrompt() {
|
|
35
|
+
return [
|
|
36
|
+
"## Analysis soft-route (stats plan)",
|
|
37
|
+
"While analysis mode is active, clear statistical / data-analysis intents soft-takeover into `/skill:analysis-plan` without waiting for an explicit slash from the user.",
|
|
38
|
+
"Stages: clarify + light EDA → structured proposal → soft human confirm (`/plan confirm`) → plan review (`/plan review`) → `/plan run` (now) or `/plan defer` (later).",
|
|
39
|
+
"Default backend: local reproducible scripts under `analysis/scripts/`. MCP only for special backends or explicit request.",
|
|
40
|
+
"Do not merge this with academic/ARS planning. After an accepted/completed plan (and results), update `analysis/HANDOFF.md` before switching to academic.",
|
|
41
|
+
"Explicit `/skill:` or `/plan` always wins over soft routing. Academic writing intents belong in academic mode.",
|
|
42
|
+
].join("\n");
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=stats-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats-router.js","sourceRoot":"","sources":["../../../src/analysis/stats-router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,YAAY,GAAG,gNAAgN,CAAC;AAEtO,MAAM,aAAa,GAAG,oHAAoH,CAAC;AAE3I,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,iDAAiD,CAAC;AAE5E,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACtF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACzD,OAAO;QACL,sBAAsB;QACtB,EAAE;QACF,6HAA6H;QAC7H,qEAAqE;QACrE,4JAA4J;QAC5J,+FAA+F;QAC/F,oIAAoI;QACpI,eAAe;QACf,QAAQ,CAAC,IAAI,EAAE;KAChB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,qCAAqC;QACrC,yKAAyK;QACzK,uKAAuK;QACvK,2HAA2H;QAC3H,0JAA0J;QAC1J,gHAAgH;KACjH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Academic-mode soft router: natural-language intent → a small allowlist of
|
|
3
|
+
* bundled writing/review skills. Skills outside this set must be invoked
|
|
4
|
+
* explicitly with `/skill:<name>` (or equivalent).
|
|
5
|
+
*/
|
|
6
|
+
export declare const ACADEMIC_SOFT_ROUTE_SKILLS: readonly ["deep-research", "academic-paper", "academic-paper-reviewer", "academic-pipeline", "academic-paper-strategist", "academic-paper-composer", "nature-figure", "nature-ref-verifier", "nature-polishing"];
|
|
7
|
+
export type AcademicSoftRouteSkill = (typeof ACADEMIC_SOFT_ROUTE_SKILLS)[number];
|
|
8
|
+
export interface AcademicSoftRouteMatch {
|
|
9
|
+
skill: AcademicSoftRouteSkill;
|
|
10
|
+
reason: string;
|
|
11
|
+
/** Optional ARS/academic-paper mode hint for the skill body. */
|
|
12
|
+
modeHint?: string;
|
|
13
|
+
priority: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function isAcademicSoftRouteSkill(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Rank allowlisted skills for academic-mode natural language (deduped by skill,
|
|
18
|
+
* keeping the highest-priority rule per skill).
|
|
19
|
+
*
|
|
20
|
+
* Primary order for multi-intent asks: earliest cue in the utterance, then
|
|
21
|
+
* rule priority. That keeps “先 A 再 B” routing to A first while still
|
|
22
|
+
* surfacing B in the ranked follow-ups.
|
|
23
|
+
*/
|
|
24
|
+
export declare function rankAcademicSoftRoutes(text: string, limit?: number): AcademicSoftRouteMatch[];
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the best allowlisted skill for academic-mode natural language.
|
|
27
|
+
* Returns null when the utterance is explicit slash routing or too ambiguous.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveAcademicSoftRoute(text: string): AcademicSoftRouteMatch | null;
|
|
30
|
+
/** Expand a soft-route match into a Pi skill invocation the user need not type. */
|
|
31
|
+
export declare function formatAcademicSoftRouteInvocation(match: AcademicSoftRouteMatch, userText: string, also?: AcademicSoftRouteMatch[]): string;
|
|
32
|
+
/** System-prompt contract for academic sticky mode. */
|
|
33
|
+
export declare function academicSoftRoutePrompt(): string;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Academic-mode soft router: natural-language intent → a small allowlist of
|
|
3
|
+
* bundled writing/review skills. Skills outside this set must be invoked
|
|
4
|
+
* explicitly with `/skill:<name>` (or equivalent).
|
|
5
|
+
*/
|
|
6
|
+
export const ACADEMIC_SOFT_ROUTE_SKILLS = [
|
|
7
|
+
"deep-research",
|
|
8
|
+
"academic-paper",
|
|
9
|
+
"academic-paper-reviewer",
|
|
10
|
+
"academic-pipeline",
|
|
11
|
+
"academic-paper-strategist",
|
|
12
|
+
"academic-paper-composer",
|
|
13
|
+
"nature-figure",
|
|
14
|
+
"nature-ref-verifier",
|
|
15
|
+
"nature-polishing",
|
|
16
|
+
];
|
|
17
|
+
const ROUTE_RULES = [
|
|
18
|
+
{
|
|
19
|
+
skill: "nature-figure",
|
|
20
|
+
reason: "figure / plotting request",
|
|
21
|
+
priority: 100,
|
|
22
|
+
pattern: /nature[- ]?figure|配图|作图|画图|出图|科研绘图|论文图表|森林图|forest\s*plot|可视化图|manuscript figure|publication[- ]ready (figure|plot)|graphical abstract|机制示意|投稿级配图|投稿级.{0,6}图/i,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
skill: "nature-ref-verifier",
|
|
26
|
+
reason: "citation field cross-check",
|
|
27
|
+
priority: 95,
|
|
28
|
+
pattern: /nature[- ]?ref|引用交叉|核对引用字段|交叉核验|多源字段核验|cross[- ]?check (refs?|citations?)|doi.*(核验|核对|verify)|verify.*(doi|citation|reference)|作者年份/i,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
skill: "nature-polishing",
|
|
32
|
+
reason: "prose polish / finalization",
|
|
33
|
+
priority: 90,
|
|
34
|
+
pattern: /nature[- ]?polish|润色|polish(ing)? (the )?(prose|manuscript|paper|abstract)|终稿润色|语言润色|submission[- ]ready polish|只做.{0,8}润色|不改(结论|数据|引用|结构).{0,12}润色|润色.{0,12}不改(结论|数据|引用)/i,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
skill: "academic-paper-strategist",
|
|
38
|
+
reason: "outline / writing strategy",
|
|
39
|
+
priority: 88,
|
|
40
|
+
pattern: /strategist|写作策略|优化大纲|规划大纲|详细大纲|paper strategy|optimize (the )?outline|重构论证|贡献点|大纲权衡|动笔前/i,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
skill: "academic-paper-composer",
|
|
44
|
+
reason: "compose full manuscript from outline",
|
|
45
|
+
priority: 86,
|
|
46
|
+
pattern: /composer|按大纲写|按.{0,6}大纲写成|执行大纲|写成全文|写完整篇|通篇写作|compose (the )?(full )?manuscript|write (the )?paper from (this |the )?outline|execute the outline|章节级质量/i,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
skill: "academic-paper-reviewer",
|
|
50
|
+
reason: "peer review / revision coaching",
|
|
51
|
+
priority: 84,
|
|
52
|
+
pattern: /reviewer|peer review|同行评审|模拟审稿|改稿|revision coach|rebuttal|点对点回复|审稿意见|方法学质疑/i,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
skill: "academic-pipeline",
|
|
56
|
+
reason: "full ARS academic pipeline",
|
|
57
|
+
priority: 82,
|
|
58
|
+
pattern: /academic[- ]?pipeline|完整流水线|全流程写作|完整.{0,8}pipeline|端到端.{0,8}pipeline|end[- ]to[- ]end (paper|manuscript) pipeline|从选题到成稿/i,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
skill: "deep-research",
|
|
62
|
+
reason: "literature research / synthesis",
|
|
63
|
+
priority: 78,
|
|
64
|
+
pattern: /deep[- ]?research|文献调研|文献检索|系统综述检索|annotated bibliography|knowledge map|文献地图|知识地图|检索式|可纳入的研究/i,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
skill: "academic-paper",
|
|
68
|
+
reason: "ARS academic-paper lit-review mode",
|
|
69
|
+
modeHint: "lit-review",
|
|
70
|
+
priority: 70,
|
|
71
|
+
pattern: /lit[- ]?review|文献综述(节|章节|写作)?|literature review section|放入论文引言/i,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
skill: "academic-paper",
|
|
75
|
+
reason: "ARS academic-paper abstract mode",
|
|
76
|
+
modeHint: "abstract",
|
|
77
|
+
priority: 69,
|
|
78
|
+
pattern: /\babstract\b|写摘要|摘要撰写|structured abstract|写一个.{0,12}abstract/i,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
skill: "academic-paper",
|
|
82
|
+
reason: "ARS academic-paper outline mode",
|
|
83
|
+
modeHint: "outline",
|
|
84
|
+
priority: 68,
|
|
85
|
+
pattern: /(?<!详细|优化|规划|重构)(写大纲|论文大纲|section outline)|\boutline\b(?!.*strategist)/i,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
skill: "academic-paper",
|
|
89
|
+
reason: "ARS academic-paper citation-check mode",
|
|
90
|
+
modeHint: "citation-check",
|
|
91
|
+
priority: 72,
|
|
92
|
+
pattern: /citation[- ]?check|引用检查|核对文末参考文献|reference list check|引文和文末|一一对应/i,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
skill: "academic-paper",
|
|
96
|
+
reason: "ARS academic-paper writing / format",
|
|
97
|
+
modeHint: "writing",
|
|
98
|
+
priority: 50,
|
|
99
|
+
pattern: /写论文|撰写论文|manuscript(?!\s+prose)|学术写作|format convert|排版导出|转 docx|转 pdf/i,
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
const EXPLICIT_SKILL_OR_ARS = /^\/(?:skill:|ars(?:-|\b)|create-|agents\b|init\b|verify\b|grill\b|review\b|loop\b|mcp\b|plugin\b|provider\b|panel\b|pet\b|help\b|export\b)/i;
|
|
103
|
+
/** Out-of-allowlist or non-academic intents that must not soft-route. */
|
|
104
|
+
const HARD_NEGATIVE = /academic-grill|逐题追问|(独立样本|配对|重复测量).{0,6}t\s*检验|跑一下.{0,12}(回归|方差|anova)|不要写论文|今天天气/i;
|
|
105
|
+
export function isAcademicSoftRouteSkill(name) {
|
|
106
|
+
return ACADEMIC_SOFT_ROUTE_SKILLS.includes(name.trim());
|
|
107
|
+
}
|
|
108
|
+
function matchIndex(text, pattern) {
|
|
109
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
110
|
+
const re = new RegExp(pattern.source, flags);
|
|
111
|
+
const hit = re.exec(text);
|
|
112
|
+
return hit?.index ?? Number.POSITIVE_INFINITY;
|
|
113
|
+
}
|
|
114
|
+
function matchesFor(text) {
|
|
115
|
+
const hits = [];
|
|
116
|
+
for (const rule of ROUTE_RULES) {
|
|
117
|
+
const index = matchIndex(text, rule.pattern);
|
|
118
|
+
if (!Number.isFinite(index))
|
|
119
|
+
continue;
|
|
120
|
+
hits.push({
|
|
121
|
+
skill: rule.skill,
|
|
122
|
+
reason: rule.reason,
|
|
123
|
+
priority: rule.priority,
|
|
124
|
+
index,
|
|
125
|
+
...(rule.modeHint ? { modeHint: rule.modeHint } : {}),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return hits;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Rank allowlisted skills for academic-mode natural language (deduped by skill,
|
|
132
|
+
* keeping the highest-priority rule per skill).
|
|
133
|
+
*
|
|
134
|
+
* Primary order for multi-intent asks: earliest cue in the utterance, then
|
|
135
|
+
* rule priority. That keeps “先 A 再 B” routing to A first while still
|
|
136
|
+
* surfacing B in the ranked follow-ups.
|
|
137
|
+
*/
|
|
138
|
+
export function rankAcademicSoftRoutes(text, limit = ACADEMIC_SOFT_ROUTE_SKILLS.length) {
|
|
139
|
+
const trimmed = text.trim();
|
|
140
|
+
if (!trimmed || EXPLICIT_SKILL_OR_ARS.test(trimmed) || HARD_NEGATIVE.test(trimmed))
|
|
141
|
+
return [];
|
|
142
|
+
const bestBySkill = new Map();
|
|
143
|
+
for (const hit of matchesFor(trimmed)) {
|
|
144
|
+
const existing = bestBySkill.get(hit.skill);
|
|
145
|
+
if (!existing || hit.priority > existing.priority || (hit.priority === existing.priority && hit.index < existing.index)) {
|
|
146
|
+
bestBySkill.set(hit.skill, hit);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return [...bestBySkill.values()]
|
|
150
|
+
.sort((a, b) => a.index - b.index || b.priority - a.priority || a.skill.localeCompare(b.skill))
|
|
151
|
+
.slice(0, Math.max(0, limit))
|
|
152
|
+
.map(({ index: _index, ...match }) => match);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the best allowlisted skill for academic-mode natural language.
|
|
156
|
+
* Returns null when the utterance is explicit slash routing or too ambiguous.
|
|
157
|
+
*/
|
|
158
|
+
export function resolveAcademicSoftRoute(text) {
|
|
159
|
+
return rankAcademicSoftRoutes(text, 1)[0] ?? null;
|
|
160
|
+
}
|
|
161
|
+
/** Expand a soft-route match into a Pi skill invocation the user need not type. */
|
|
162
|
+
export function formatAcademicSoftRouteInvocation(match, userText, also = []) {
|
|
163
|
+
const modeLine = match.modeHint
|
|
164
|
+
? `Preferred mode / focus: ${match.modeHint}.`
|
|
165
|
+
: "";
|
|
166
|
+
const followUps = also
|
|
167
|
+
.filter((item) => item.skill !== match.skill)
|
|
168
|
+
.map((item) => item.skill);
|
|
169
|
+
const followLine = followUps.length > 0
|
|
170
|
+
? `After the primary skill, continue with these allowlisted skills in order when the user request clearly needs them: ${followUps.join(" → ")}.`
|
|
171
|
+
: "";
|
|
172
|
+
return [
|
|
173
|
+
`/skill:${match.skill}`,
|
|
174
|
+
"",
|
|
175
|
+
`Academic soft-route (${match.reason}). Load and follow this skill now; do not ask the user to retype /skill:${match.skill}.`,
|
|
176
|
+
modeLine,
|
|
177
|
+
followLine,
|
|
178
|
+
"User request:",
|
|
179
|
+
userText.trim(),
|
|
180
|
+
].filter((line) => line !== undefined && line !== "").join("\n");
|
|
181
|
+
}
|
|
182
|
+
/** System-prompt contract for academic sticky mode. */
|
|
183
|
+
export function academicSoftRoutePrompt() {
|
|
184
|
+
const list = ACADEMIC_SOFT_ROUTE_SKILLS.map((name) => `- ${name}`).join("\n");
|
|
185
|
+
return [
|
|
186
|
+
"## Academic soft-route (allowlist only)",
|
|
187
|
+
"While academic mode is active, you may silently load and follow only these bundled skills without waiting for an explicit `/skill:` from the user:",
|
|
188
|
+
list,
|
|
189
|
+
"Routing preference (pick one primary skill, state it briefly, then proceed; for clearly multi-step asks, chain allowlisted skills in order):",
|
|
190
|
+
"- Literature search / synthesis → deep-research",
|
|
191
|
+
"- Paper-format lit-review / abstract / outline / citation-check / manuscript drafting → academic-paper",
|
|
192
|
+
"- Peer review / revision / rebuttal → academic-paper-reviewer",
|
|
193
|
+
"- End-to-end ARS pipeline → academic-pipeline",
|
|
194
|
+
"- Writing strategy / optimized outline → academic-paper-strategist",
|
|
195
|
+
"- Execute outline into full manuscript → academic-paper-composer",
|
|
196
|
+
"- Publication figures → nature-figure",
|
|
197
|
+
"- DOI/author/year field cross-check after citation work → nature-ref-verifier",
|
|
198
|
+
"- Final prose polish only → nature-polishing",
|
|
199
|
+
"Invoke the chosen skill via `/skill:<name>` (or the host skill tool) so the user can see it, then follow that skill. Do not ask the user to type the slash command when the intent is clear.",
|
|
200
|
+
"Skills outside this allowlist must NOT be auto-selected. If another skill is needed, tell the user to run `/skill:<name>` explicitly (or `/skill` to manage installs).",
|
|
201
|
+
"Explicit user `/skill:` or `/ars-*` always wins over soft routing.",
|
|
202
|
+
].join("\n");
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=academic-router.js.map
|