wtf-p 0.7.3 → 0.8.0
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 +16 -12
- package/bin/commands/install-logic.js +1 -1
- package/bin/lib/adapter-compiler.js +175 -56
- package/bin/lib/clio-registration.js +127 -36
- package/bin/lib/manifest.js +11 -3
- package/bin/uninstall.js +3 -2
- package/package.json +1 -1
- package/protocol/actions/research-gap.json +1 -1
- package/protocol/roles/research-synthesizer.md +1 -1
- package/protocol/skills/wtfp-plan-section/references/actions.md +1 -1
- package/protocol/skills/wtfp-research-literature/references/actions.md +1 -1
- package/protocol/skills/wtfp-write-section/references/actions.md +1 -1
- package/protocol/workflows/plan-section.md +3 -2
- package/protocol/workflows/research-gap.md +2 -2
- package/protocol/workflows/write-section.md +1 -1
- package/vendors/antigravity/.wtfp-generated.json +18 -14
- package/vendors/antigravity/actions/research-gap.json +1 -1
- package/vendors/antigravity/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/antigravity/commands/wtfp-plan-section.md +3 -2
- package/vendors/antigravity/commands/wtfp-write-section.md +1 -1
- package/vendors/antigravity/plugin.json +1 -1
- package/vendors/antigravity/roles/research-synthesizer.md +1 -1
- package/vendors/antigravity/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/antigravity/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/antigravity/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/antigravity/tools/README.md +1 -1
- package/vendors/antigravity/tools/package.json +1 -0
- package/vendors/antigravity/workflows/plan-section.md +3 -2
- package/vendors/antigravity/workflows/research-gap.md +2 -2
- package/vendors/antigravity/workflows/write-section.md +1 -1
- package/vendors/claude/.claude-plugin/marketplace.json +2 -2
- package/vendors/claude/.claude-plugin/plugin.json +1 -1
- package/vendors/claude/.wtfp-generated.json +33 -29
- package/vendors/claude/actions/research-gap.json +1 -1
- package/vendors/claude/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/claude/ai.iowarp.clio/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/analyze-bib.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/check-refs.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/create-outline.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/execute-outline.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/help.md +1 -1
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/plan-section.md +5 -2
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/polish-prose.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/quick.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/research-gap.md +8 -2
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/review-section.md +2 -0
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/write-section.md +3 -1
- package/vendors/claude/commands/plan-section.md +3 -2
- package/vendors/claude/commands/research-gap.md +2 -2
- package/vendors/claude/commands/write-section.md +1 -1
- package/vendors/claude/plugin.json +1 -1
- package/vendors/claude/roles/research-synthesizer.md +1 -1
- package/vendors/claude/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/claude/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/claude/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/claude/tools/README.md +1 -1
- package/vendors/claude/tools/package.json +1 -0
- package/vendors/claude/workflows/plan-section.md +3 -2
- package/vendors/claude/workflows/research-gap.md +2 -2
- package/vendors/claude/workflows/write-section.md +1 -1
- package/vendors/clio-extension/.wtfp-generated.json +228 -0
- package/vendors/clio-extension/actions/add-todo.json +52 -0
- package/vendors/clio-extension/actions/analyze-bib.json +97 -0
- package/vendors/clio-extension/actions/audit-milestone.json +63 -0
- package/vendors/clio-extension/actions/check-refs.json +80 -0
- package/vendors/clio-extension/actions/check-todos.json +52 -0
- package/vendors/clio-extension/actions/checkpoint.json +76 -0
- package/vendors/clio-extension/actions/contribute.json +57 -0
- package/vendors/clio-extension/actions/create-outline.json +84 -0
- package/vendors/clio-extension/actions/create-poster.json +54 -0
- package/vendors/clio-extension/actions/create-slides.json +54 -0
- package/vendors/clio-extension/actions/discuss-section.json +76 -0
- package/vendors/clio-extension/actions/execute-outline.json +116 -0
- package/vendors/clio-extension/actions/export-latex.json +65 -0
- package/vendors/clio-extension/actions/help.json +30 -0
- package/vendors/clio-extension/actions/insert-section.json +61 -0
- package/vendors/clio-extension/actions/list-assumptions.json +35 -0
- package/vendors/clio-extension/actions/map-project.json +71 -0
- package/vendors/clio-extension/actions/new-paper.json +70 -0
- package/vendors/clio-extension/actions/pause-writing.json +71 -0
- package/vendors/clio-extension/actions/plan-milestone-gaps.json +57 -0
- package/vendors/clio-extension/actions/plan-revision.json +58 -0
- package/vendors/clio-extension/actions/plan-section.json +100 -0
- package/vendors/clio-extension/actions/polish-prose.json +69 -0
- package/vendors/clio-extension/actions/progress.json +51 -0
- package/vendors/clio-extension/actions/quick.json +70 -0
- package/vendors/clio-extension/actions/remove-section.json +63 -0
- package/vendors/clio-extension/actions/report-bug.json +47 -0
- package/vendors/clio-extension/actions/request-feature.json +47 -0
- package/vendors/clio-extension/actions/research-gap.json +102 -0
- package/vendors/clio-extension/actions/resume-writing.json +65 -0
- package/vendors/clio-extension/actions/review-section.json +83 -0
- package/vendors/clio-extension/actions/settings.json +47 -0
- package/vendors/clio-extension/actions/submit-milestone.json +77 -0
- package/vendors/clio-extension/actions/update.json +42 -0
- package/vendors/clio-extension/actions/verify-work.json +63 -0
- package/vendors/clio-extension/actions/write-section.json +115 -0
- package/vendors/clio-extension/clio-coder-extension.yaml +53 -0
- package/vendors/clio-extension/compatibility/action-availability.json +295 -0
- package/vendors/clio-extension/project/schemas/checkpoint.schema.json +102 -0
- package/vendors/clio-extension/project/schemas/common.schema.json +33 -0
- package/vendors/clio-extension/project/schemas/config.schema.json +69 -0
- package/vendors/clio-extension/project/schemas/decisions.schema.json +31 -0
- package/vendors/clio-extension/project/schemas/evidence.schema.json +48 -0
- package/vendors/clio-extension/project/schemas/manifest.schema.json +102 -0
- package/vendors/clio-extension/project/schemas/outline.schema.json +67 -0
- package/vendors/clio-extension/project/schemas/section.schema.json +95 -0
- package/vendors/clio-extension/project/schemas/source.schema.json +73 -0
- package/vendors/clio-extension/project/schemas/state.schema.json +58 -0
- package/vendors/clio-extension/project/schemas/validation.schema.json +74 -0
- package/vendors/clio-extension/runtime/extension.test.ts +248 -0
- package/vendors/clio-extension/runtime/extension.ts +1321 -0
- package/vendors/clio-extension/runtime/json-schema.cjs +304 -0
- package/vendors/clio-extension/runtime/package.json +3 -0
- package/vendors/clio-extension/runtime/write-guard.json +21 -0
- package/vendors/clio-extension/skins/wtfp.json +20 -0
- package/vendors/codex/plugins/wtfp/.codex-plugin/plugin.json +1 -1
- package/vendors/codex/plugins/wtfp/.wtfp-generated.json +17 -13
- package/vendors/codex/plugins/wtfp/actions/research-gap.json +1 -1
- package/vendors/codex/plugins/wtfp/agents/wtfp-research-synthesizer.toml +1 -1
- package/vendors/codex/plugins/wtfp/plugin.json +1 -1
- package/vendors/codex/plugins/wtfp/roles/research-synthesizer.md +1 -1
- package/vendors/codex/plugins/wtfp/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/codex/plugins/wtfp/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/codex/plugins/wtfp/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/codex/plugins/wtfp/tools/README.md +1 -1
- package/vendors/codex/plugins/wtfp/tools/package.json +1 -0
- package/vendors/codex/plugins/wtfp/workflows/plan-section.md +3 -2
- package/vendors/codex/plugins/wtfp/workflows/research-gap.md +2 -2
- package/vendors/codex/plugins/wtfp/workflows/write-section.md +1 -1
- package/vendors/copilot/.wtfp-generated.json +14 -14
- package/vendors/copilot/marketplace.json +2 -2
- package/vendors/copilot/plugins/wtfp/.claude-plugin/plugin.json +1 -1
- package/vendors/copilot/plugins/wtfp/.wtfp-generated.json +18 -14
- package/vendors/copilot/plugins/wtfp/actions/research-gap.json +1 -1
- package/vendors/copilot/plugins/wtfp/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/copilot/plugins/wtfp/commands/wtfp-plan-section.md +3 -2
- package/vendors/copilot/plugins/wtfp/commands/wtfp-write-section.md +1 -1
- package/vendors/copilot/plugins/wtfp/roles/research-synthesizer.md +1 -1
- package/vendors/copilot/plugins/wtfp/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/copilot/plugins/wtfp/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/copilot/plugins/wtfp/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/copilot/plugins/wtfp/tools/README.md +1 -1
- package/vendors/copilot/plugins/wtfp/tools/package.json +1 -0
- package/vendors/copilot/plugins/wtfp/workflows/plan-section.md +3 -2
- package/vendors/copilot/plugins/wtfp/workflows/research-gap.md +2 -2
- package/vendors/copilot/plugins/wtfp/workflows/write-section.md +1 -1
- package/vendors/copilot/project/.github/agents/wtfp-research-synthesizer.agent.md +1 -1
- package/vendors/copilot/project/.github/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/copilot/project/.github/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/copilot/project/.github/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/copilot/project/.github/wtfp/actions/research-gap.json +1 -1
- package/vendors/copilot/project/.github/wtfp/roles/research-synthesizer.md +1 -1
- package/vendors/copilot/project/.github/wtfp/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/copilot/project/.github/wtfp/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/copilot/project/.github/wtfp/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/copilot/project/.github/wtfp/workflows/plan-section.md +3 -2
- package/vendors/copilot/project/.github/wtfp/workflows/research-gap.md +2 -2
- package/vendors/copilot/project/.github/wtfp/workflows/write-section.md +1 -1
- package/vendors/gemini/.wtfp-generated.json +24 -20
- package/vendors/gemini/actions/research-gap.json +1 -1
- package/vendors/gemini/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/gemini/commands/wtfp/discuss-section.toml +1 -1
- package/vendors/gemini/commands/wtfp/execute-outline.toml +1 -1
- package/vendors/gemini/commands/wtfp/insert-section.toml +1 -1
- package/vendors/gemini/commands/wtfp/list-assumptions.toml +1 -1
- package/vendors/gemini/commands/wtfp/plan-revision.toml +1 -1
- package/vendors/gemini/commands/wtfp/plan-section.toml +4 -3
- package/vendors/gemini/commands/wtfp/quick.toml +1 -1
- package/vendors/gemini/commands/wtfp/write-section.toml +2 -2
- package/vendors/gemini/gemini-extension.json +1 -1
- package/vendors/gemini/roles/research-synthesizer.md +1 -1
- package/vendors/gemini/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/gemini/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/gemini/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/gemini/tools/README.md +1 -1
- package/vendors/gemini/tools/package.json +1 -0
- package/vendors/gemini/workflows/plan-section.md +3 -2
- package/vendors/gemini/workflows/research-gap.md +2 -2
- package/vendors/gemini/workflows/write-section.md +1 -1
- package/vendors/opencode/.wtfp-generated.json +23 -19
- package/vendors/opencode/actions/research-gap.json +1 -1
- package/vendors/opencode/agents/wtfp/research-synthesizer.md +1 -1
- package/vendors/opencode/commands/wtfp/discuss-section.md +1 -1
- package/vendors/opencode/commands/wtfp/execute-outline.md +1 -1
- package/vendors/opencode/commands/wtfp/insert-section.md +1 -1
- package/vendors/opencode/commands/wtfp/list-assumptions.md +1 -1
- package/vendors/opencode/commands/wtfp/plan-revision.md +1 -1
- package/vendors/opencode/commands/wtfp/plan-section.md +4 -3
- package/vendors/opencode/commands/wtfp/quick.md +1 -1
- package/vendors/opencode/commands/wtfp/write-section.md +2 -2
- package/vendors/opencode/roles/research-synthesizer.md +1 -1
- package/vendors/opencode/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/opencode/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/opencode/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/opencode/tools/README.md +1 -1
- package/vendors/opencode/tools/package.json +1 -0
- package/vendors/opencode/workflows/plan-section.md +3 -2
- package/vendors/opencode/workflows/research-gap.md +2 -2
- package/vendors/opencode/workflows/write-section.md +1 -1
- package/vendors/plugin/.wtfp-generated.json +44 -40
- package/vendors/plugin/actions/research-gap.json +1 -1
- package/vendors/plugin/ai.iowarp.clio/agents/wtfp-research-synthesizer.md +1 -1
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/add-todo.md +6 -12
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/analyze-bib.md +9 -19
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/audit-milestone.md +7 -25
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/check-refs.md +9 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/check-todos.md +9 -13
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/checkpoint.md +7 -27
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/create-outline.md +9 -25
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/discuss-section.md +7 -17
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/execute-outline.md +10 -27
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/help.md +2 -2
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/insert-section.md +7 -13
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/map-project.md +6 -14
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/new-paper.md +7 -17
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/pause-writing.md +6 -18
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/plan-milestone-gaps.md +7 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/plan-section.md +12 -29
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/polish-prose.md +10 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/quick.md +10 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/research-gap.md +15 -23
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/resume-writing.md +7 -23
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/review-section.md +9 -19
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/settings.md +7 -9
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/submit-milestone.md +7 -25
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/verify-work.md +7 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/write-section.md +11 -29
- package/vendors/plugin/compatibility/action-availability.json +16 -1
- package/vendors/plugin/plugin.json +7 -7
- package/vendors/plugin/roles/research-synthesizer.md +1 -1
- package/vendors/plugin/skills/wtfp-plan-section/references/actions.md +1 -1
- package/vendors/plugin/skills/wtfp-research-literature/references/actions.md +1 -1
- package/vendors/plugin/skills/wtfp-write-section/references/actions.md +1 -1
- package/vendors/plugin/tools/README.md +1 -1
- package/vendors/plugin/tools/package.json +1 -0
- package/vendors/plugin/workflows/plan-section.md +3 -2
- package/vendors/plugin/workflows/research-gap.md +2 -2
- package/vendors/plugin/workflows/write-section.md +1 -1
- /package/vendors/plugin/ai.iowarp.clio/{fleets → playbooks}/wtfp-draft-review.md +0 -0
- /package/vendors/plugin/ai.iowarp.clio/{fleets → playbooks}/wtfp-plan-section.md +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
// Generated by WTF-P adapter compiler v5 from clio/runtime/extension.test.ts; do not edit.
|
|
2
|
+
/**
|
|
3
|
+
* Package tests for the WTF-P desk, run by `clio-coder extensions test
|
|
4
|
+
* vendors/clio-extension`. One case per runtime tool, the write guard, the
|
|
5
|
+
* desk workspace and the desk without its plugin, each against a small valid
|
|
6
|
+
* project in a task-owned TMPDIR. The kit serves no plugin unless a case
|
|
7
|
+
* passes one.
|
|
8
|
+
*/
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { test } from "node:test";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { createExtensionTestHost } from "@iowarp/clio-coder/extensions/testing";
|
|
15
|
+
|
|
16
|
+
const ROOT = fileURLToPath(new URL("../", import.meta.url));
|
|
17
|
+
const PROJECT = "desk-test";
|
|
18
|
+
const AT = "2026-10-01T12:00:00Z";
|
|
19
|
+
const GATE = "checkpoint-framing";
|
|
20
|
+
|
|
21
|
+
function project(): string {
|
|
22
|
+
assert.ok(process.env.TMPDIR, "Tests need a task-owned TMPDIR.");
|
|
23
|
+
const workspace = mkdtempSync(path.join(process.env.TMPDIR, "wtfp-desk-test-"));
|
|
24
|
+
const put = (relative: string, value: unknown): void => {
|
|
25
|
+
mkdirSync(path.dirname(path.join(workspace, relative)), { recursive: true });
|
|
26
|
+
writeFileSync(path.join(workspace, relative), typeof value === "string" ? value : `${JSON.stringify(value, null, 2)}\n`);
|
|
27
|
+
};
|
|
28
|
+
put(".planning/project.json", {
|
|
29
|
+
schema: "wtfp.project.manifest/v1",
|
|
30
|
+
protocol_version: 1,
|
|
31
|
+
id: PROJECT,
|
|
32
|
+
title: "Logging on Shared Memory",
|
|
33
|
+
document_type: "research-article",
|
|
34
|
+
core_argument: "Shared memory removes the flush bottleneck without weakening durability.",
|
|
35
|
+
target: { audience: "Storage researchers", word_limit: 100 },
|
|
36
|
+
requirements: { must_have: [], should_have: [], out_of_scope: [] },
|
|
37
|
+
created_at: AT,
|
|
38
|
+
updated_at: AT,
|
|
39
|
+
artifacts: {
|
|
40
|
+
manifest: "project://manifest",
|
|
41
|
+
config: "project://config",
|
|
42
|
+
state: "project://state",
|
|
43
|
+
decisions: "project://decisions",
|
|
44
|
+
outline: "project://structure/outline",
|
|
45
|
+
materials: [],
|
|
46
|
+
manuscripts: [],
|
|
47
|
+
deliverables: [],
|
|
48
|
+
archives: [],
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
put(".planning/config.json", {
|
|
52
|
+
schema: "wtfp.project.config/v1",
|
|
53
|
+
project_id: PROJECT,
|
|
54
|
+
interaction_mode: "standard",
|
|
55
|
+
depth: "standard",
|
|
56
|
+
output_format: "markdown",
|
|
57
|
+
language: "en-US",
|
|
58
|
+
citation_style: "author-date",
|
|
59
|
+
gates: { confirm_outline: true, confirm_plan: true, confirm_write: true, confirm_review: true, confirm_delivery: true },
|
|
60
|
+
workflow: { research: true, plan_validation: true, argument_validation: true, coherence_validation: true },
|
|
61
|
+
safety: { destructive_requires_authorization: true, external_publish_requires_authorization: true, backup_before_major_edits: true },
|
|
62
|
+
parallelism: { enabled: false, max_workers: 1 },
|
|
63
|
+
});
|
|
64
|
+
put(".planning/state.json", {
|
|
65
|
+
schema: "wtfp.project.state/v1",
|
|
66
|
+
project_id: PROJECT,
|
|
67
|
+
revision: 3,
|
|
68
|
+
phase: "writing",
|
|
69
|
+
status: "active",
|
|
70
|
+
current_section_uri: "project://sections/introduction",
|
|
71
|
+
progress: { sections_total: 1, sections_complete: 0, word_target: 100, word_count: 0 },
|
|
72
|
+
active_checkpoint_uris: [`project://checkpoints/${GATE}`],
|
|
73
|
+
last_transition: { from: "planning", to: "writing", reason: "The plan is approved.", at: AT },
|
|
74
|
+
updated_at: AT,
|
|
75
|
+
});
|
|
76
|
+
put(".planning/structure/outline.json", {
|
|
77
|
+
schema: "wtfp.project.outline/v1",
|
|
78
|
+
project_id: PROJECT,
|
|
79
|
+
revision: 1,
|
|
80
|
+
thesis: "Shared memory removes the flush bottleneck without weakening durability.",
|
|
81
|
+
target_words: 100,
|
|
82
|
+
sections: [
|
|
83
|
+
{
|
|
84
|
+
id: "introduction",
|
|
85
|
+
title: "Introduction",
|
|
86
|
+
goal: "State the flush bottleneck and the contribution.",
|
|
87
|
+
argument_role: "setup",
|
|
88
|
+
word_target: 100,
|
|
89
|
+
wave: 1,
|
|
90
|
+
depends_on: [],
|
|
91
|
+
claim_ids: [],
|
|
92
|
+
research: { required: false, topics: [] },
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
updated_at: AT,
|
|
96
|
+
});
|
|
97
|
+
put(".planning/sections/introduction/section.json", {
|
|
98
|
+
schema: "wtfp.project.section/v1",
|
|
99
|
+
id: "introduction",
|
|
100
|
+
project_id: PROJECT,
|
|
101
|
+
outline_uri: "project://structure/outline",
|
|
102
|
+
title: "Introduction",
|
|
103
|
+
goal: "State the flush bottleneck and the contribution.",
|
|
104
|
+
status: "planned",
|
|
105
|
+
word_target: 100,
|
|
106
|
+
word_count: 0,
|
|
107
|
+
wave: 1,
|
|
108
|
+
depends_on: [],
|
|
109
|
+
claims: [],
|
|
110
|
+
artifacts: {
|
|
111
|
+
context: "project://sections/introduction/context",
|
|
112
|
+
research: "project://sections/introduction/research",
|
|
113
|
+
plans: ["project://sections/introduction/plans/initial"],
|
|
114
|
+
reviews: [],
|
|
115
|
+
manuscript: "project://paper/introduction",
|
|
116
|
+
},
|
|
117
|
+
checkpoint_uris: [`project://checkpoints/${GATE}`],
|
|
118
|
+
validation_uris: [],
|
|
119
|
+
updated_at: AT,
|
|
120
|
+
});
|
|
121
|
+
put(`.planning/checkpoints/${GATE}.json`, {
|
|
122
|
+
schema: "wtfp.project.checkpoint/v1",
|
|
123
|
+
id: GATE,
|
|
124
|
+
project_id: PROJECT,
|
|
125
|
+
kind: "decision",
|
|
126
|
+
status: "pending",
|
|
127
|
+
blocking: true,
|
|
128
|
+
scope_uri: "project://sections/introduction",
|
|
129
|
+
request: "Lead with the protocol or with the workflow?",
|
|
130
|
+
options: [
|
|
131
|
+
{ id: "protocol-first", label: "Protocol first", implication: "Lead with interoperability." },
|
|
132
|
+
{ id: "workflow-first", label: "Workflow first", implication: "Lead with the end-to-end process." },
|
|
133
|
+
],
|
|
134
|
+
resume_action: "write-section",
|
|
135
|
+
created_at: AT,
|
|
136
|
+
});
|
|
137
|
+
// Eleven body words: front matter, the heading, the citation key and the code block do not count.
|
|
138
|
+
put(
|
|
139
|
+
"paper/introduction.md",
|
|
140
|
+
"---\ntitle: Introduction\n---\n# Introduction\n\nShared memory changes the cost of logging [@smith2024]. It's a well-known trade-off.\n\n```c\nint flush = 1;\n```\n",
|
|
141
|
+
);
|
|
142
|
+
return workspace;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type Json = Record<string, unknown>;
|
|
146
|
+
const read = (workspace: string, relative: string): Json => JSON.parse(readFileSync(path.join(workspace, relative), "utf8")) as Json;
|
|
147
|
+
|
|
148
|
+
const SERVED = { id: "wtfp", prompts: ["wtfp:check-todos", "wtfp:plan-section", "wtfp:progress", "wtfp:write-section"] };
|
|
149
|
+
|
|
150
|
+
async function withDesk(
|
|
151
|
+
run: (host: Awaited<ReturnType<typeof createExtensionTestHost>>, workspace: string) => Promise<void>,
|
|
152
|
+
plugin: typeof SERVED | null = null,
|
|
153
|
+
): Promise<void> {
|
|
154
|
+
const workspace = project();
|
|
155
|
+
const host = await createExtensionTestHost(ROOT, { workspace, plugin });
|
|
156
|
+
try {
|
|
157
|
+
await run(host, workspace);
|
|
158
|
+
} finally {
|
|
159
|
+
await host.dispose();
|
|
160
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
test("record writes a validated record at the revision the caller read and refuses a stale or invalid one", () =>
|
|
165
|
+
withDesk(async (host, workspace) => {
|
|
166
|
+
const state = read(workspace, ".planning/state.json");
|
|
167
|
+
const written = await host.tool("record", { uri: "project://state", record: { ...state, phase: "reviewing" }, expect_revision: 3 });
|
|
168
|
+
assert.equal(written.isError, undefined, written.text);
|
|
169
|
+
assert.deepEqual(written.data, { uri: "project://state", file: ".planning/state.json", revision: 4 });
|
|
170
|
+
assert.equal(read(workspace, ".planning/state.json").phase, "reviewing");
|
|
171
|
+
const stale = await host.tool("record", { uri: "project://state", record: { ...state, phase: "ready" }, expect_revision: 3 });
|
|
172
|
+
assert.equal(stale.isError, true);
|
|
173
|
+
assert.match(stale.text, /revision 4, not 3/);
|
|
174
|
+
const invalid = await host.tool("record", { uri: "project://state", record: { ...state, phase: "drafting" } });
|
|
175
|
+
assert.equal(invalid.isError, true);
|
|
176
|
+
assert.match(invalid.text, /would not validate/);
|
|
177
|
+
assert.deepEqual([read(workspace, ".planning/state.json").phase, read(workspace, ".planning/state.json").revision], ["reviewing", 4]);
|
|
178
|
+
}));
|
|
179
|
+
|
|
180
|
+
test("measure_section counts body words by the desk's one method and records them in the section and state", () =>
|
|
181
|
+
withDesk(async (host, workspace) => {
|
|
182
|
+
const measured = await host.tool("measure_section", { section: "introduction" });
|
|
183
|
+
assert.equal(measured.isError, undefined, measured.text);
|
|
184
|
+
assert.deepEqual(measured.data, { words: 11, target: 100, file: "paper/introduction.md", total: 11 });
|
|
185
|
+
assert.equal(read(workspace, ".planning/sections/introduction/section.json").word_count, 11);
|
|
186
|
+
assert.equal((read(workspace, ".planning/state.json").progress as Json).word_count, 11);
|
|
187
|
+
}));
|
|
188
|
+
|
|
189
|
+
test("gate asks the author and records only the author's answer", () =>
|
|
190
|
+
withDesk(async (host, workspace) => {
|
|
191
|
+
const asked = await host.tool("gate", { checkpoint: GATE });
|
|
192
|
+
assert.equal(asked.interview?.id, "gate-one");
|
|
193
|
+
assert.equal(asked.interview?.step.key, GATE);
|
|
194
|
+
assert.equal(read(workspace, `.planning/checkpoints/${GATE}.json`).status, "pending");
|
|
195
|
+
const answered = await host.interview({ id: "gate-one", step: GATE, nav: "next", answers: { choice: "workflow-first" } });
|
|
196
|
+
assert.match("done" in answered ? answered.text : "", /Recorded the author's answer/);
|
|
197
|
+
const checkpoint = read(workspace, `.planning/checkpoints/${GATE}.json`);
|
|
198
|
+
assert.equal(checkpoint.status, "resolved");
|
|
199
|
+
assert.deepEqual(
|
|
200
|
+
[(checkpoint.resolution as Json).resolved_by, (checkpoint.resolution as Json).selected_option],
|
|
201
|
+
["author", "workflow-first"],
|
|
202
|
+
);
|
|
203
|
+
assert.deepEqual(read(workspace, ".planning/state.json").active_checkpoint_uris, []);
|
|
204
|
+
}));
|
|
205
|
+
|
|
206
|
+
test("the write guard refuses a write outside the roots the armed action declares", () =>
|
|
207
|
+
withDesk(async (host) => {
|
|
208
|
+
const armed = await host.hook({ point: "prompt_submit", text: "/wtfp:write-section introduction" });
|
|
209
|
+
assert.equal(armed.effects?.[0]?.kind, "notify_operator");
|
|
210
|
+
const refused = await host.hook({ point: "before_tool", tool: "write", turnId: "t1", args: { path: "src/notes.md" } });
|
|
211
|
+
const effect = refused.effects?.[0];
|
|
212
|
+
assert.equal(effect?.kind, "block_tool");
|
|
213
|
+
assert.match(effect && "reason" in effect ? effect.reason : "", /\/wtfp:write-section may write only under \.planning, paper; refused src\/notes\.md/);
|
|
214
|
+
}, SERVED));
|
|
215
|
+
|
|
216
|
+
test("the desk enters with its four regions and clears its ambient UI when left in a folder with no project", async () => {
|
|
217
|
+
assert.ok(process.env.TMPDIR, "Tests need a task-owned TMPDIR.");
|
|
218
|
+
const workspace = mkdtempSync(path.join(process.env.TMPDIR, "wtfp-desk-empty-"));
|
|
219
|
+
const host = await createExtensionTestHost(ROOT, { workspace });
|
|
220
|
+
try {
|
|
221
|
+
const entered = await host.command("desk");
|
|
222
|
+
assert.deepEqual(entered.workspace, { enter: "desk" });
|
|
223
|
+
assert.deepEqual(Object.keys(entered.regions ?? {}), ["header", "board", "rail", "footer"]);
|
|
224
|
+
assert.match(JSON.stringify(entered.band), /new-paper/);
|
|
225
|
+
const left = await host.observe({ event: "workspace_leave", workspace: "desk" });
|
|
226
|
+
assert.deepEqual(left, { text: "", status: null, band: null, islands: null });
|
|
227
|
+
} finally {
|
|
228
|
+
await host.dispose();
|
|
229
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("without its plugin the desk names only its own commands and never a /wtfp: prompt", () =>
|
|
234
|
+
withDesk(async (host) => {
|
|
235
|
+
const outputs: unknown[] = [];
|
|
236
|
+
for (const name of ["desk", "progress", "help", "check-todos", "checkpoints", "validate"]) outputs.push(await host.command(name));
|
|
237
|
+
for (const id of ["next", "help"]) outputs.push(await host.action(id));
|
|
238
|
+
outputs.push(await host.action("section", "introduction"));
|
|
239
|
+
outputs.push(await host.hook({ point: "prompt_submit", text: "/wtfp:write-section introduction" }));
|
|
240
|
+
outputs.push(await host.hook({ point: "before_tool", tool: "write", turnId: "t1", args: { path: "src/notes.md" } }));
|
|
241
|
+
await host.hook({ point: "prompt_submit", text: "plain text" });
|
|
242
|
+
outputs.push(await host.hook({ point: "before_tool", tool: "write", turnId: "t1", args: { path: "paper/introduction.md" } }));
|
|
243
|
+
outputs.push(await host.observe({ event: "session_open", reason: "startup" }));
|
|
244
|
+
const emitted = JSON.stringify(outputs);
|
|
245
|
+
assert.doesNotMatch(emitted, /\/wtfp:/);
|
|
246
|
+
assert.match(emitted, /\/ext:wtfp:check-todos/);
|
|
247
|
+
assert.match(emitted, /needs the WTF-P plugin|not installed and enabled/);
|
|
248
|
+
}));
|