wtf-p 0.7.4 → 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 +10 -10
- package/bin/commands/install-logic.js +1 -1
- package/bin/lib/adapter-compiler.js +163 -55
- 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/vendors/antigravity/.wtfp-generated.json +2 -2
- package/vendors/antigravity/plugin.json +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 +5 -5
- package/vendors/claude/ai.iowarp.clio/prompts/wtfp/help.md +1 -1
- package/vendors/claude/plugin.json +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 +3 -3
- package/vendors/codex/plugins/wtfp/plugin.json +1 -1
- package/vendors/copilot/.wtfp-generated.json +2 -2
- 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 +2 -2
- package/vendors/gemini/.wtfp-generated.json +2 -2
- package/vendors/gemini/gemini-extension.json +1 -1
- package/vendors/plugin/.wtfp-generated.json +30 -30
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/add-todo.md +6 -12
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/analyze-bib.md +7 -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 +7 -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 +7 -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 +8 -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 +7 -27
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/polish-prose.md +8 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/quick.md +8 -15
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/research-gap.md +7 -21
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/resume-writing.md +7 -23
- package/vendors/plugin/ai.iowarp.clio/prompts/wtfp/review-section.md +7 -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 +8 -28
- package/vendors/plugin/compatibility/action-availability.json +16 -1
- package/vendors/plugin/plugin.json +7 -7
- /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
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ the scientific judgment. The agent keeps the bookkeeping and does bounded jobs.
|
|
|
19
19
|
|
|
20
20
|
It ships as one canonical [Agent Plugins 1.0.0](https://agent-plugins.org)
|
|
21
21
|
bundle that a deterministic compiler projects into a native package for seven
|
|
22
|
-
coding-agent hosts. Version `0.
|
|
22
|
+
coding-agent hosts. Version `0.8.0` is the current stable release and is
|
|
23
23
|
what npm `latest` resolves to; v0.5 remains installable by explicit version.
|
|
24
24
|
|
|
25
25
|
**Optional CiteNexus research backend (since 0.7.0):** `citation-search --backend=cite-nexus`
|
|
@@ -56,18 +56,18 @@ registers it with the host's native plugin lifecycle where one exists.
|
|
|
56
56
|
|
|
57
57
|
| Host | Install | Native registration the installer performs | Verified with |
|
|
58
58
|
| --- | --- | --- | --- |
|
|
59
|
-
| Clio Coder (0.
|
|
60
|
-
| Claude Code | `npx --yes --package=wtf-p@0.
|
|
61
|
-
| Codex | `npx --yes --package=wtf-p@0.
|
|
62
|
-
| GitHub Copilot CLI | `npx --yes --package=wtf-p@0.
|
|
63
|
-
| OpenCode | `npx --yes --package=wtf-p@0.
|
|
64
|
-
| Antigravity CLI | `npx --yes --package=wtf-p@0.
|
|
65
|
-
| Gemini CLI | `npx --yes --package=wtf-p@0.
|
|
59
|
+
| Clio Coder (0.6.2 or newer) | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install clio` | `clio-coder library install <staged-bundle> --user` and `clio-coder library inspect wtfp --user --json`, then `clio-coder extensions install <staged-extension> --user` and `clio-coder extensions list --user --json` | 0.6.2-dev (local build `89ea1b4`) |
|
|
60
|
+
| Claude Code | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install claude` | `claude plugin marketplace add <root>/marketplaces/wtfp --scope user`, then `claude plugin install wtfp@wtfp --scope user -y` | 2.1.274 |
|
|
61
|
+
| Codex | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install codex` | `codex plugin marketplace add <root>/marketplaces/wtfp`, then `codex plugin add wtfp@wtfp --json`; agents copied to `$CODEX_HOME/agents/` | 0.153.3 |
|
|
62
|
+
| GitHub Copilot CLI | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install copilot` | `copilot plugin marketplace add <root>/marketplaces/wtfp`, then `copilot plugin install wtfp@wtfp` | 1.0.85 |
|
|
63
|
+
| OpenCode | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install opencode` | Files under the OpenCode config root; OpenCode discovers them by directory | 1.18.31 |
|
|
64
|
+
| Antigravity CLI | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install antigravity` | `agy plugin install <root>/sources/wtfp` | 1.2.5 |
|
|
65
|
+
| Gemini CLI | `npx --yes --package=wtf-p@0.8.0 -- wtf-p install gemini` | Files under `<root>/extensions/wtfp`; Gemini discovers the extension by directory | 0.60.0 |
|
|
66
66
|
|
|
67
67
|
"Verified" means native discovery in a disposable profile on this exact
|
|
68
68
|
envelope, with the commands recorded in
|
|
69
69
|
[Host capabilities](docs/HOST_CAPABILITIES.md). Clio Coder is published as
|
|
70
|
-
`@iowarp/clio-coder`; 0.
|
|
70
|
+
`@iowarp/clio-coder`; 0.6.2 and newer carry the plugin and extension engine WTF-P uses.
|
|
71
71
|
Clio Coder itself requires Node.js 22.19 or newer.
|
|
72
72
|
|
|
73
73
|
Keep the explicit `--package=wtf-p@<version> -- wtf-p` form. On a workstation
|
|
@@ -77,7 +77,7 @@ the old executable instead.
|
|
|
77
77
|
## Sixty-second start
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
npx --yes --package=wtf-p@0.
|
|
80
|
+
npx --yes --package=wtf-p@0.8.0 -- wtf-p install clio
|
|
81
81
|
cd /path/to/your-paper-or-proposal
|
|
82
82
|
clio-coder --autonomy full-auto
|
|
83
83
|
```
|
|
@@ -816,7 +816,7 @@ async function install(runtime, isUpdate, options, pkg) {
|
|
|
816
816
|
// the installer stages a distinct copy and registers it.
|
|
817
817
|
const scope = targetDir === path.join(process.cwd(), '.clio-coder') ? 'project' : 'user';
|
|
818
818
|
const configFlag = explicitConfigDir ? ` --config-dir '${targetDir.replaceAll("'", "'\\''")}'` : '';
|
|
819
|
-
out.warn(`Activation is pending: once clio-coder is on PATH, re-run npx wtf-p install clio${configFlag} from this directory to register the ${scope}-scope plugin.`);
|
|
819
|
+
out.warn(`Activation is pending: once clio-coder is on PATH, re-run npx wtf-p install clio${configFlag} from this directory to register the ${scope}-scope plugin and extension.`);
|
|
820
820
|
}
|
|
821
821
|
} else if (nativeActivation.status === 'deferred' && !hasQuiet) {
|
|
822
822
|
out.warn(`${nativeActivation.reason}. The WTF-P bundle is staged but native registration is pending.`);
|
|
@@ -7,6 +7,8 @@ const { GENERATOR_VERSION } = require('./adapter-metadata');
|
|
|
7
7
|
|
|
8
8
|
const ROOT = path.resolve(__dirname, '../..');
|
|
9
9
|
const PROTOCOL_ROOT = path.join(ROOT, 'protocol');
|
|
10
|
+
// Human-edited source of the standalone Clio extension; see clio/README.md.
|
|
11
|
+
const CLIO_RUNTIME_ROOT = path.join(ROOT, 'clio');
|
|
10
12
|
const INVENTORY_NAME = '.wtfp-generated.json';
|
|
11
13
|
|
|
12
14
|
const TARGET_ROOTS = Object.freeze({
|
|
@@ -494,7 +496,7 @@ function projectSchemasForAction(action) {
|
|
|
494
496
|
return [...schemas].sort((left, right) => left.localeCompare(right));
|
|
495
497
|
}
|
|
496
498
|
|
|
497
|
-
function nativeCommandBody(action, workflowBody, target) {
|
|
499
|
+
function nativeCommandBody(action, workflowBody, target, deskTools = false) {
|
|
498
500
|
const argumentToken = target === 'gemini'
|
|
499
501
|
? '{{args}}'
|
|
500
502
|
: target === 'copilot-cloud'
|
|
@@ -503,17 +505,17 @@ function nativeCommandBody(action, workflowBody, target) {
|
|
|
503
505
|
const schemas = projectSchemasForAction(action);
|
|
504
506
|
const protocolIncludes = [
|
|
505
507
|
`@protocol://actions/${action.id}.json`,
|
|
506
|
-
...(schemas.length > 0 ? ['@protocol://project/schemas/common.schema.json'] : []),
|
|
507
|
-
...schemas.flatMap((schema) => [
|
|
508
|
+
...(!deskTools && schemas.length > 0 ? ['@protocol://project/schemas/common.schema.json'] : []),
|
|
509
|
+
...(!deskTools ? schemas : []).flatMap((schema) => [
|
|
508
510
|
`@protocol://project/schemas/${schema}.schema.json`,
|
|
509
511
|
`@protocol://project/templates/${schema}.json`
|
|
510
512
|
])
|
|
511
513
|
];
|
|
512
514
|
return [
|
|
513
515
|
nativeWorkflowBody([
|
|
514
|
-
workflowBody,
|
|
516
|
+
deskTools ? clioDeskWorkflowBody(action, workflowBody) : workflowBody,
|
|
515
517
|
'',
|
|
516
|
-
'## Bound action contract and schemas',
|
|
518
|
+
deskTools ? '## Bound action contract' : '## Bound action contract and schemas',
|
|
517
519
|
'',
|
|
518
520
|
...protocolIncludes
|
|
519
521
|
].join('\n'), target),
|
|
@@ -596,8 +598,13 @@ function generatedScriptBanner(kind, id) {
|
|
|
596
598
|
return `// Generated by WTF-P adapter compiler v${GENERATOR_VERSION} from ${kind}/${id}; do not edit.`;
|
|
597
599
|
}
|
|
598
600
|
|
|
599
|
-
function clioUserGateBody(action) {
|
|
601
|
+
function clioUserGateBody(action, deskTools = false) {
|
|
600
602
|
if (!action.effects.some((effect) => effect.id === 'user.gate')) return '';
|
|
603
|
+
if (deskTools) return [
|
|
604
|
+
'## Clio user-gate binding',
|
|
605
|
+
'',
|
|
606
|
+
'For a pending checkpoint in the declared gate\'s exact scope, call `extension_wtfp__gate` with its ID. Create a missing pending checkpoint through `extension_wtfp__record` only when this action declares checkpoint creation; otherwise use `ask_user` for the unpersisted author decision and do not invent an undeclared output. Only the structured author answer satisfies the gate; cancelled, retained or expired checkpoints authorize nothing. Never write `resolution.resolved_by: author` yourself or infer approval from invocation text, prose or silence. Read back a persisted resolution before applying its gated mutation.'
|
|
607
|
+
].join('\n');
|
|
601
608
|
return [
|
|
602
609
|
'## Clio user-gate binding',
|
|
603
610
|
'',
|
|
@@ -605,6 +612,30 @@ function clioUserGateBody(action) {
|
|
|
605
612
|
].join('\n');
|
|
606
613
|
}
|
|
607
614
|
|
|
615
|
+
// Only the canonical Clio namespace prefers the optional desk. The unrooted
|
|
616
|
+
// phase-1 projection remains intact for the Claude envelope and other hosts.
|
|
617
|
+
function clioDeskWorkflowBody(action, workflowBody) {
|
|
618
|
+
let body = workflowBody
|
|
619
|
+
.replace(/^@protocol:\/\/project\/README\.md\n/gm, '')
|
|
620
|
+
.replace(/^@protocol:\/\/skills\/[^\n]+\/references\/actions\.md\n/gm, '')
|
|
621
|
+
.replace(/^Resolve every logical URI through the host adapter\.[^\n]+$/m,
|
|
622
|
+
'Use `extension_wtfp__record` for each declared JSON record write: pass its logical `uri`, complete `record`, and the revision read as `expect_revision` for revisioned updates. It validates, bumps revisions/timestamps, replaces atomically and reads back; preserve stable IDs and author decisions.')
|
|
623
|
+
.replace(/^Manuscript prose and supporting context,[^\n]+$/m,
|
|
624
|
+
'Write prose and linked artifacts with native file tools; keep their authored formats. The record tool handles JSON records only, never manuscript text, deletion or archives.');
|
|
625
|
+
if (action.id === 'write-section') body = body.replace(/^3\. Read the persisted manuscript text back[^\n]+$/m,
|
|
626
|
+
'3. Read back the persisted manuscript, call `extension_wtfp__measure_section` with its section ID, and use the returned body count and target tolerance for validation and the summary; never use a worker self-report or hand-count words.');
|
|
627
|
+
if (action.id === 'check-todos') body = body
|
|
628
|
+
.replace(/^2\. Ask the user[^\n]+$/m, '2. Call `extension_wtfp__gate` for each selected pending checkpoint; the parked interview records the author\'s answer.')
|
|
629
|
+
.replace(/^3\. Apply only[^\n]+$/m, '3. Read back the resulting checkpoint and state; retained or cancelled gates remain pending.');
|
|
630
|
+
const bindings = [
|
|
631
|
+
'Discover the named tools with `gateway(op="describe", capability="extension_wtfp__record")` (and the corresponding `measure_section` or `gate` name), then use `gateway(op="call", capability="<exact name>", args={...})`. A present tool\'s error or refusal stops the action; never bypass it with a manual write or shell script.',
|
|
632
|
+
...(action.produces.some((output) => output.uri.startsWith('project://paper')) && action.id !== 'write-section'
|
|
633
|
+
? ['After changing a linked section manuscript, call `extension_wtfp__measure_section` with that section ID; it persists the desk\'s body-word count in the section and state.'] : []),
|
|
634
|
+
`If desk tools are absent, follow \`\${pluginRoot}/workflows/${action.id}.md\` and \`\${pluginRoot}/project/README.md\` with native tools and \`ask_user\` gates.`
|
|
635
|
+
];
|
|
636
|
+
return `${body}\n\n${bindings.join('\n')}`;
|
|
637
|
+
}
|
|
638
|
+
|
|
608
639
|
function clioResearchConnectionBody(action) {
|
|
609
640
|
if (action.id !== 'research-gap') return '';
|
|
610
641
|
return [
|
|
@@ -645,7 +676,8 @@ function helpArgumentHint(action) {
|
|
|
645
676
|
// Clio renders a display-only prompt by printing its first fenced block to the
|
|
646
677
|
// operator without a model call. The block is a self-contained reference:
|
|
647
678
|
// no includes, no procedure, only what a human needs to pick the next action.
|
|
648
|
-
|
|
679
|
+
// `legacyFleetNames` renders the pre-playbook wording the Claude envelope keeps.
|
|
680
|
+
function clioHelpCard(model, availabilityById, legacyFleetNames = false) {
|
|
649
681
|
const byId = new Map(model.actions.map((action) => [action.id, action]));
|
|
650
682
|
const line = (id) => {
|
|
651
683
|
const action = byId.get(id);
|
|
@@ -661,7 +693,7 @@ function clioHelpCard(model, availabilityById) {
|
|
|
661
693
|
if (!groupIds.has(skill.id)) throw new Error(`help card has no group order for skill ${skill.id}`);
|
|
662
694
|
}
|
|
663
695
|
for (const id of HELP_START_SEQUENCE) if (!byId.has(id)) throw new Error(`help card start sequence names an unknown action: ${id}`);
|
|
664
|
-
const
|
|
696
|
+
const playbooks = fs.readdirSync(path.join(PROTOCOL_ROOT, 'fleets'))
|
|
665
697
|
.filter((file) => file.endsWith('.json')).sort()
|
|
666
698
|
.map((file) => readJson(path.join(PROTOCOL_ROOT, 'fleets', file)));
|
|
667
699
|
const card = [
|
|
@@ -677,8 +709,10 @@ function clioHelpCard(model, availabilityById) {
|
|
|
677
709
|
'Product operations',
|
|
678
710
|
...model.catalog.operations.actions.map(line),
|
|
679
711
|
'',
|
|
680
|
-
|
|
681
|
-
|
|
712
|
+
legacyFleetNames
|
|
713
|
+
? 'Fleets (clio-coder fleet run <fleet> --var section=<section>; explicit fleet primitives, not auto-routed)'
|
|
714
|
+
: 'Playbooks (clio-coder fleet run <playbook> --var section=<section>; run explicitly, never auto-routed)',
|
|
715
|
+
...playbooks.map((playbook) => ` ${playbook.id}\n ${playbook.description}`),
|
|
682
716
|
'',
|
|
683
717
|
'Each action reads .planning/ records and paper/ artifacts, asks before any gated write, and never runs Git or publishes.',
|
|
684
718
|
'An unavailable action fails closed with WTFP_ACTION_UNAVAILABLE and returns a manual handoff instead.'
|
|
@@ -699,7 +733,7 @@ function clioHelpCard(model, availabilityById) {
|
|
|
699
733
|
].join('\n');
|
|
700
734
|
}
|
|
701
735
|
|
|
702
|
-
function renderMarkdownCommand(action, workflowBody, target, availability) {
|
|
736
|
+
function renderMarkdownCommand(action, workflowBody, target, availability, deskTools = false) {
|
|
703
737
|
const lines = ['---'];
|
|
704
738
|
// Claude derives the stable command name from the plugin id and flat file
|
|
705
739
|
// name. Repeating either in frontmatter creates names such as
|
|
@@ -721,9 +755,9 @@ function renderMarkdownCommand(action, workflowBody, target, availability) {
|
|
|
721
755
|
for (const tool of tools) lines.push(` - ${tool}`);
|
|
722
756
|
}
|
|
723
757
|
}
|
|
724
|
-
const nativeBody = nativeCommandBody(action, workflowBody, target);
|
|
758
|
+
const nativeBody = nativeCommandBody(action, workflowBody, target, deskTools);
|
|
725
759
|
const clioRoles = action.delegation.map((entry) => `\`wtfp-${entry.role}\``).join(', ');
|
|
726
|
-
const userGateBody = target === 'clio' ? [clioUserGateBody(action), clioResearchConnectionBody(action), action.delegation.length ? `## Clio role-result binding\n\nDispatch the declared specialist roles using these exact Clio agent IDs: ${clioRoles}. Do not substitute generic coder or verifier agents. If a named agent is unavailable, report that blocker and stop instead of silently changing roles.\n\nRead the single wtfp.role-result entry in native validations/checks and parse its evidence string as portable role-result JSON. Validate its schema, role and action against the dispatched task. Missing, duplicate or malformed outcomes fail closed. On needs_input ask the author through ask_user and redispatch with the response; on blocked or failed stop and report the issue. Only completed permits downstream work, and it never substitutes for an author gate or artifact readback.` : ''].filter(Boolean).join('\n\n') : '';
|
|
760
|
+
const userGateBody = target === 'clio' ? [clioUserGateBody(action, deskTools), clioResearchConnectionBody(action), action.delegation.length ? `## Clio role-result binding\n\nDispatch the declared specialist roles using these exact Clio agent IDs: ${clioRoles}. Do not substitute generic coder or verifier agents. If a named agent is unavailable, report that blocker and stop instead of silently changing roles.\n\nRead the single wtfp.role-result entry in native validations/checks and parse its evidence string as portable role-result JSON. Validate its schema, role and action against the dispatched task. Missing, duplicate or malformed outcomes fail closed. On needs_input ask the author through ask_user and redispatch with the response; on blocked or failed stop and report the issue. Only completed permits downstream work, and it never substitutes for an author gate or artifact readback.` : ''].filter(Boolean).join('\n\n') : '';
|
|
727
761
|
lines.push(
|
|
728
762
|
'---',
|
|
729
763
|
'',
|
|
@@ -948,6 +982,41 @@ function standardPluginManifest(version, name = 'wtfp', clioExtension) {
|
|
|
948
982
|
});
|
|
949
983
|
}
|
|
950
984
|
|
|
985
|
+
const CLIO_PLAYBOOKS = ['wtfp-plan-section', 'wtfp-draft-review'];
|
|
986
|
+
|
|
987
|
+
// The root manifest with the Clio namespace. Clio runs fleet contracts as
|
|
988
|
+
// playbooks. `legacyFleetNames` keeps the pre-playbook `fleets` key, kind and
|
|
989
|
+
// directory for the Claude envelope, whose Clio copy Clio no longer adopts.
|
|
990
|
+
function clioPluginManifest(model, legacyFleetNames = false) {
|
|
991
|
+
const playbookRoot = `ai.iowarp.clio/${legacyFleetNames ? 'fleets' : 'playbooks'}`;
|
|
992
|
+
const components = [];
|
|
993
|
+
for (const action of model.actions) components.push({
|
|
994
|
+
kind: 'prompt', id: action.id,
|
|
995
|
+
path: `ai.iowarp.clio/prompts/wtfp/${action.id}.md`,
|
|
996
|
+
requires: action.delegation.map(item => `agent:${item.role}`)
|
|
997
|
+
});
|
|
998
|
+
for (const role of model.roles) components.push({
|
|
999
|
+
kind: 'agent', id: role.slug, path: `ai.iowarp.clio/agents/wtfp-${role.slug}.md`,
|
|
1000
|
+
requires: [`skill:${ROLE_SKILLS[role.slug]}`]
|
|
1001
|
+
});
|
|
1002
|
+
for (const skill of model.catalog.skills) components.push({
|
|
1003
|
+
kind: 'skill', id: skill.id, path: `skills/${skill.id}/SKILL.md`, requires: []
|
|
1004
|
+
});
|
|
1005
|
+
for (const id of CLIO_PLAYBOOKS) components.push({
|
|
1006
|
+
kind: legacyFleetNames ? 'fleet' : 'playbook', id, path: `${playbookRoot}/${id}.md`, requires: []
|
|
1007
|
+
});
|
|
1008
|
+
return standardPluginManifest(model.version, 'wtfp', {
|
|
1009
|
+
manifestVersion: 1,
|
|
1010
|
+
// The Claude copy keeps its pre-playbook floor; Clio 0.6.1 and older reject `playbooks`.
|
|
1011
|
+
compatibility: { clio: legacyFleetNames ? '>=0.4.7' : '>=0.6.2' },
|
|
1012
|
+
resources: {
|
|
1013
|
+
skills: 'skills', prompts: 'ai.iowarp.clio/prompts', agents: 'ai.iowarp.clio/agents',
|
|
1014
|
+
[legacyFleetNames ? 'fleets' : 'playbooks']: playbookRoot
|
|
1015
|
+
},
|
|
1016
|
+
components
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
|
|
951
1020
|
function clioFleetWriteBoundary(resource, fleetId) {
|
|
952
1021
|
if (/^project:\/\/paper(?:\/|$)/u.test(resource)) return 'paper/';
|
|
953
1022
|
if (/^project:\/\//u.test(resource)) return '.planning/';
|
|
@@ -1198,15 +1267,23 @@ function actionWriteRoots(action) {
|
|
|
1198
1267
|
return [...roots].sort((left, right) => left.localeCompare(right));
|
|
1199
1268
|
}
|
|
1200
1269
|
|
|
1201
|
-
// The
|
|
1202
|
-
//
|
|
1203
|
-
//
|
|
1204
|
-
function
|
|
1270
|
+
// The manuscript-writing actions (those that produce `project://paper/...`)
|
|
1271
|
+
// available on one host, each with the project roots it declares. Both write
|
|
1272
|
+
// guards arm on exactly these.
|
|
1273
|
+
function manuscriptGuardActions(model, availabilityById, host) {
|
|
1205
1274
|
const guarded = model.actions
|
|
1206
1275
|
.filter((action) => availabilityById.get(action.id).available)
|
|
1207
1276
|
.filter((action) => action.produces.some((output) => output.uri.startsWith('project://paper')))
|
|
1208
1277
|
.map((action) => [action.id, actionWriteRoots(action)]);
|
|
1209
|
-
if (guarded.length === 0) throw new Error(
|
|
1278
|
+
if (guarded.length === 0) throw new Error(`no manuscript-writing action is available on ${host}`);
|
|
1279
|
+
return guarded;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// The Claude write guard arms on the manuscript-writing actions, confines
|
|
1283
|
+
// Write/Edit calls for the rest of that prompt to the roots the action
|
|
1284
|
+
// declares, and disarms when the turn stops.
|
|
1285
|
+
function claudeWriteGuard(model, availabilityById) {
|
|
1286
|
+
const guarded = manuscriptGuardActions(model, availabilityById, 'Claude');
|
|
1210
1287
|
const manifest = stableJson({
|
|
1211
1288
|
schema: 'wtfp.claude-write-guard/v1',
|
|
1212
1289
|
actions: Object.fromEntries(guarded)
|
|
@@ -1338,6 +1415,31 @@ function geminiManifest(version) {
|
|
|
1338
1415
|
});
|
|
1339
1416
|
}
|
|
1340
1417
|
|
|
1418
|
+
// The Clio extension is installed and consented independently of the content
|
|
1419
|
+
// plugin. Every file its runtime reads belongs to this package; the plugin
|
|
1420
|
+
// link controls prompt takeover, not filesystem access to another install.
|
|
1421
|
+
function addClioRuntime(plan, model, availabilityById) {
|
|
1422
|
+
const source = (relative) => fs.readFileSync(path.join(CLIO_RUNTIME_ROOT, relative), 'utf8');
|
|
1423
|
+
const manifest = source('clio-coder-extension.yaml').replace(/^(?:#.*\n)+/, '');
|
|
1424
|
+
if (!/^version: .*$/m.test(manifest)) throw new Error('clio/clio-coder-extension.yaml must declare a version line');
|
|
1425
|
+
addFile(plan, 'clio-coder-extension.yaml', [
|
|
1426
|
+
`# Generated by WTF-P adapter compiler v${GENERATOR_VERSION} from clio/clio-coder-extension.yaml; do not edit.`,
|
|
1427
|
+
manifest.replace(/^version: .*$/m, `version: ${model.version}`)
|
|
1428
|
+
].join('\n'));
|
|
1429
|
+
addFile(plan, 'runtime/extension.ts', `${generatedScriptBanner('clio', 'runtime/extension.ts')}\n${source('runtime/extension.ts')}`);
|
|
1430
|
+
// `clio-coder extensions test vendors/clio-extension` runs the package tests from here.
|
|
1431
|
+
addFile(plan, 'runtime/extension.test.ts', `${generatedScriptBanner('clio', 'runtime/extension.test.ts')}\n${source('runtime/extension.test.ts')}`);
|
|
1432
|
+
addFile(plan, 'runtime/package.json', source('runtime/package.json'));
|
|
1433
|
+
addFile(plan, 'runtime/json-schema.cjs', `${generatedScriptBanner('evaluation', 'lib/json-schema.js')}\n${fs.readFileSync(path.join(ROOT, 'evaluation', 'lib', 'json-schema.js'), 'utf8')}`);
|
|
1434
|
+
addFile(plan, 'runtime/write-guard.json', stableJson({
|
|
1435
|
+
schema: 'wtfp.clio-write-guard/v1',
|
|
1436
|
+
actions: Object.fromEntries(manuscriptGuardActions(model, availabilityById, 'Clio'))
|
|
1437
|
+
}));
|
|
1438
|
+
addFile(plan, 'skins/wtfp.json', source('skins/wtfp.json'));
|
|
1439
|
+
copyTree(plan, path.join(PROTOCOL_ROOT, 'project', 'schemas'), 'project/schemas');
|
|
1440
|
+
copyTree(plan, path.join(PROTOCOL_ROOT, 'actions'), 'actions');
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1341
1443
|
function makePlan(id, root) {
|
|
1342
1444
|
return { id, root, files: new Map() };
|
|
1343
1445
|
}
|
|
@@ -1800,11 +1902,11 @@ function compilePlans(options = {}) {
|
|
|
1800
1902
|
availabilityByTarget.set(plan.id, addActionAvailability(plan, model, plan.id, targetPolicies));
|
|
1801
1903
|
}
|
|
1802
1904
|
|
|
1803
|
-
for (const fleetId of
|
|
1905
|
+
for (const fleetId of CLIO_PLAYBOOKS) {
|
|
1804
1906
|
if (!clio.files.delete(`fleets/${fleetId}.json`)) {
|
|
1805
1907
|
throw new Error(`cannot project missing canonical fleet for Clio: ${fleetId}`);
|
|
1806
1908
|
}
|
|
1807
|
-
addFile(clio, `
|
|
1909
|
+
addFile(clio, `playbooks/${fleetId}.md`, clioFleet(fleetId));
|
|
1808
1910
|
}
|
|
1809
1911
|
|
|
1810
1912
|
const claude = byId.get('claude');
|
|
@@ -1883,47 +1985,53 @@ function compilePlans(options = {}) {
|
|
|
1883
1985
|
addFile(codex, `agents/wtfp-${role.slug}.toml`, renderCodexAgent(role, role.slug));
|
|
1884
1986
|
}
|
|
1885
1987
|
|
|
1886
|
-
// The canonical
|
|
1988
|
+
// The canonical content-only plugin. Its prompts also work without the desk.
|
|
1887
1989
|
const portable = makePlan('portable-plugin', path.join(ROOT, 'vendors', 'plugin'));
|
|
1888
1990
|
for (const [file, content] of clio.files) {
|
|
1889
|
-
const native = /^(prompts|agents|
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
compatibility: { clio: '>=0.4.7' },
|
|
1911
|
-
resources: { skills: 'skills', prompts: 'ai.iowarp.clio/prompts', agents: 'ai.iowarp.clio/agents', fleets: 'ai.iowarp.clio/fleets' },
|
|
1912
|
-
components
|
|
1913
|
-
});
|
|
1914
|
-
addFile(portable, 'plugin.json', portableManifest);
|
|
1991
|
+
const native = /^(prompts|agents|playbooks)\//.test(file);
|
|
1992
|
+
const actionId = /^prompts\/wtfp\/([a-z-]+)\.md$/.exec(file)?.[1];
|
|
1993
|
+
const action = actionId && model.actions.find((entry) => entry.id === actionId);
|
|
1994
|
+
const usesRecords = action && action.produces.some((output) =>
|
|
1995
|
+
/^project:\/\/(?:manifest|config|state|decisions|structure\/outline|(?:sections|sources|evidence|checkpoints|validations)\/[^/]+)$/.test(output.uri));
|
|
1996
|
+
const projected = usesRecords && availabilityByTarget.get('clio').get(actionId).available
|
|
1997
|
+
? renderMarkdownCommand(action, action.workflowBody, 'clio', availabilityByTarget.get('clio').get(actionId), true)
|
|
1998
|
+
: content;
|
|
1999
|
+
addFile(portable, native ? `ai.iowarp.clio/${file}` : file, projected);
|
|
2000
|
+
}
|
|
2001
|
+
addFile(portable, 'plugin.json', clioPluginManifest(model));
|
|
2002
|
+
const availability = JSON.parse(portable.files.get('compatibility/action-availability.json'));
|
|
2003
|
+
// Base bindings remain usable with the content plugin alone. The separately
|
|
2004
|
+
// installed desk supplies these preferred bindings when its tools are live.
|
|
2005
|
+
availability.runtimeBindings = {
|
|
2006
|
+
plugin: 'wtfp', extension: 'wtfp',
|
|
2007
|
+
capabilities: { 'user.interaction': 'clio:extension-interview' },
|
|
2008
|
+
approvals: { explicit: 'clio:extension-interview' },
|
|
2009
|
+
tools: { record: 'extension_wtfp__record', measure_section: 'extension_wtfp__measure_section', gate: 'extension_wtfp__gate' }
|
|
2010
|
+
};
|
|
2011
|
+
replaceFile(portable, 'compatibility/action-availability.json', stableJson(availability));
|
|
1915
2012
|
plans.push(portable);
|
|
1916
2013
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
//
|
|
2014
|
+
const extension = makePlan('clio-extension', path.join(ROOT, 'vendors', 'clio-extension'));
|
|
2015
|
+
addClioRuntime(extension, model, availabilityByTarget.get('clio'));
|
|
2016
|
+
addFile(extension, 'compatibility/action-availability.json', clio.files.get('compatibility/action-availability.json'));
|
|
2017
|
+
plans.push(extension);
|
|
2018
|
+
|
|
2019
|
+
// The Claude envelope keeps its pre-playbook Clio namespace: a root `plugin.json`
|
|
2020
|
+
// and the phase 1 prompts, agents and fleets it names, beside Claude's own
|
|
2021
|
+
// `.claude-plugin/` surface. Clio no longer adopts a Claude-installed WTF-P;
|
|
2022
|
+
// it labels the copy older and points to `vendors/plugin`. Claude Code reads
|
|
2023
|
+
// neither file; its commands, agents, skills, hooks, and output style stay
|
|
2024
|
+
// where its loader looks.
|
|
1923
2025
|
for (const [file, content] of clio.files) {
|
|
1924
|
-
if (
|
|
2026
|
+
if (file === 'prompts/wtfp/help.md') {
|
|
2027
|
+
addFile(claude, `ai.iowarp.clio/${file}`, clioHelpCard(model, availabilityByTarget.get('clio'), true));
|
|
2028
|
+
} else if (/^(prompts|agents)\//.test(file)) {
|
|
2029
|
+
addFile(claude, `ai.iowarp.clio/${file}`, content);
|
|
2030
|
+
} else if (file.startsWith('playbooks/')) {
|
|
2031
|
+
addFile(claude, `ai.iowarp.clio/fleets/${file.slice('playbooks/'.length)}`, content);
|
|
2032
|
+
}
|
|
1925
2033
|
}
|
|
1926
|
-
addFile(claude, 'plugin.json',
|
|
2034
|
+
addFile(claude, 'plugin.json', clioPluginManifest(model, true));
|
|
1927
2035
|
|
|
1928
2036
|
const codexMarketplace = makePlan('codex-marketplace', path.join(ROOT, 'vendors', 'codex'));
|
|
1929
2037
|
addFile(codexMarketplace, '.agents/plugins/marketplace.json', stableJson({
|