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
|
@@ -5,9 +5,9 @@ const path = require('path');
|
|
|
5
5
|
const { createTargetGuard, resolveOwnedPath, sha256Buffer } = require('./ownership');
|
|
6
6
|
|
|
7
7
|
// Clio owns integrity, provenance, drift and enable/disable for an installed
|
|
8
|
-
// plugin. WTF-P owns two much smaller things: the exact bytes it
|
|
9
|
-
// (its v2 receipt) and the guarantee that
|
|
10
|
-
// generated
|
|
8
|
+
// plugin or extension. WTF-P owns two much smaller things: the exact bytes it
|
|
9
|
+
// publishes (its v2 receipt) and the guarantee that each tree handed to Clio
|
|
10
|
+
// is the generated package and nothing else.
|
|
11
11
|
function treeFiles(root) {
|
|
12
12
|
const files = new Map();
|
|
13
13
|
function visit(directory) {
|
|
@@ -37,10 +37,11 @@ function scopeOptions(targetDir, options) {
|
|
|
37
37
|
return { ...options, cwd, scope: project ? 'project' : 'user' };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function generatedBundle(root) {
|
|
40
|
+
function generatedBundle(root, target = 'portable-plugin') {
|
|
41
41
|
const inventoryPath = path.join(root, '.wtfp-generated.json');
|
|
42
|
+
if (!fs.existsSync(inventoryPath)) return null;
|
|
42
43
|
const inventory = JSON.parse(fs.readFileSync(inventoryPath, 'utf8'));
|
|
43
|
-
if (inventory.schema !== 'wtfp.generated-adapter/v1' || inventory.target !==
|
|
44
|
+
if (inventory.schema !== 'wtfp.generated-adapter/v1' || inventory.target !== target) {
|
|
44
45
|
return null;
|
|
45
46
|
}
|
|
46
47
|
const expected = new Map(inventory.files.map(file => [file.path, file.sha256]));
|
|
@@ -108,42 +109,110 @@ function installedListEntry(stdout, targetDir, native, scope) {
|
|
|
108
109
|
return matches[0];
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
function installedExtensionEntry(stdout, targetDir, native, scope) {
|
|
113
|
+
const listing = JSON.parse(stdout);
|
|
114
|
+
if (!listing || !Array.isArray(listing.extensions)) {
|
|
115
|
+
throw new Error('Clio extensions list did not return an extensions array');
|
|
116
|
+
}
|
|
117
|
+
for (const entry of listing.extensions) {
|
|
118
|
+
if (!installedRecord(entry)) throw new Error('Clio extensions list returned a malformed installed extension');
|
|
119
|
+
}
|
|
120
|
+
const matches = listing.extensions.filter(entry => entry.id === native.id && entry.scope === scope &&
|
|
121
|
+
sameRoot(entry.rootPath, path.join(targetDir, native.source)));
|
|
122
|
+
if (matches.length > 1) throw new Error('Clio extensions list returned duplicate installed extension identities');
|
|
123
|
+
return matches[0];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The two Clio packages WTF-P installs, plugin first. Each is its own Clio
|
|
127
|
+
// install with its own lifecycle command, generated inventory and checks.
|
|
128
|
+
function clioPackages(native) {
|
|
129
|
+
const plugin = {
|
|
130
|
+
noun: 'plugin', command: 'library', id: native.id, source: native.source, inventory: 'portable-plugin',
|
|
131
|
+
deferral: 'Clio activation requires an intact generated bundle without extra or modified files',
|
|
132
|
+
list: () => ['library', 'list', '--kind', 'plugin', '--json'],
|
|
133
|
+
listed: (stdout, targetDir, scope) => installedListEntry(stdout, targetDir, native, scope),
|
|
134
|
+
// `inspect` returns the installed record for the explicitly selected scope.
|
|
135
|
+
verify: scope => ['library', 'inspect', native.id, `--${scope}`, '--json'],
|
|
136
|
+
verified: (stdout, targetDir, scope) => verifiedEntry(stdout, targetDir, native, scope)
|
|
137
|
+
};
|
|
138
|
+
if (!native.extension) return [plugin];
|
|
139
|
+
const extension = native.extension;
|
|
140
|
+
const listed = (stdout, targetDir, scope) => installedExtensionEntry(stdout, targetDir, extension, scope);
|
|
141
|
+
return [plugin, {
|
|
142
|
+
noun: 'extension', command: 'extensions', id: extension.id, source: extension.source, inventory: 'clio-extension',
|
|
143
|
+
deferral: 'Clio extension activation requires an intact generated extension without extra or modified files',
|
|
144
|
+
list: scope => ['extensions', 'list', `--${scope}`, '--json'],
|
|
145
|
+
listed,
|
|
146
|
+
verify: scope => ['extensions', 'list', `--${scope}`, '--json'],
|
|
147
|
+
verified: listed
|
|
148
|
+
}];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Registration is what WTF-P is responsible for. Whether the operator has a
|
|
152
|
+
// package switched on is Clio's state and their decision, so it is reported,
|
|
113
153
|
// never asserted and never changed.
|
|
114
154
|
function registered(entry) {
|
|
115
155
|
return Boolean(entry) && entry.valid === true &&
|
|
116
156
|
Array.isArray(entry.diagnostics) && entry.diagnostics.length === 0;
|
|
117
157
|
}
|
|
118
158
|
|
|
119
|
-
function disabledNotice(
|
|
120
|
-
return `Clio reports ${
|
|
159
|
+
function disabledNotice(pkg, scope) {
|
|
160
|
+
return `Clio reports ${pkg.id} as installed but disabled. WTF-P does not change that preference; run clio-coder ${pkg.command} enable ${pkg.id} --${scope} to switch it back on.`;
|
|
121
161
|
}
|
|
122
162
|
|
|
163
|
+
// Install the plugin, then the extension. A failure in the second compensates
|
|
164
|
+
// the first, and the returned compensator undoes both in reverse order.
|
|
123
165
|
function activateClio(targetDir, native, suppliedOptions) {
|
|
124
166
|
const options = scopeOptions(targetDir, suppliedOptions);
|
|
167
|
+
const activated = [];
|
|
168
|
+
try {
|
|
169
|
+
for (const pkg of clioPackages(native)) {
|
|
170
|
+
const result = activatePackage(targetDir, pkg, options);
|
|
171
|
+
activated.push(result);
|
|
172
|
+
if (result.status !== 'registered') break;
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
const failures = activated.reverse().flatMap(result => typeof result.rollback === 'function' ? result.rollback() : []);
|
|
176
|
+
if (failures.length) error.nativeRollbackFailures = [...(error.nativeRollbackFailures || []), ...failures];
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
if (activated.length === 1) return activated[0];
|
|
180
|
+
const last = activated[activated.length - 1];
|
|
181
|
+
const notices = activated.map(result => result.notice).filter(Boolean);
|
|
182
|
+
return {
|
|
183
|
+
status: last.status, executable: 'clio-coder',
|
|
184
|
+
...(last.reason ? { reason: last.reason } : {}),
|
|
185
|
+
results: activated.flatMap(result => result.results),
|
|
186
|
+
...(notices.length ? { notice: notices.join(' ') } : {}),
|
|
187
|
+
rollback() {
|
|
188
|
+
return [...activated].reverse().flatMap(result => typeof result.rollback === 'function' ? result.rollback() : []);
|
|
189
|
+
},
|
|
190
|
+
commit() {
|
|
191
|
+
const warnings = activated.map(result => typeof result.commit === 'function' ? result.commit() : undefined).filter(Boolean);
|
|
192
|
+
return warnings.length ? warnings.join('; ') : undefined;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function activatePackage(targetDir, pkg, options) {
|
|
125
198
|
const { execute, environment } = options;
|
|
126
199
|
const guard = createTargetGuard(targetDir);
|
|
127
|
-
const root = resolveOwnedPath(targetDir,
|
|
200
|
+
const root = resolveOwnedPath(targetDir, pkg.source, guard);
|
|
128
201
|
const publishedFiles = treeFiles(root);
|
|
129
|
-
const expected = generatedBundle(root);
|
|
202
|
+
const expected = generatedBundle(root, pkg.inventory);
|
|
130
203
|
if (!expected || !sameTree(expected, publishedFiles)) {
|
|
131
|
-
return {
|
|
132
|
-
status: 'deferred',
|
|
133
|
-
reason: 'Clio activation requires an intact generated bundle without extra or modified files',
|
|
134
|
-
results: []
|
|
135
|
-
};
|
|
204
|
+
return { status: 'deferred', reason: pkg.deferral, results: [] };
|
|
136
205
|
}
|
|
137
206
|
|
|
138
207
|
const results = [];
|
|
139
|
-
const priorList = execute('clio-coder',
|
|
208
|
+
const priorList = execute('clio-coder', pkg.list(options.scope), environment, options);
|
|
140
209
|
if (priorList.status === 'unavailable') return { status: 'unavailable', executable: 'clio-coder', results };
|
|
141
210
|
results.push(priorList);
|
|
142
|
-
const priorEntry =
|
|
211
|
+
const priorEntry = pkg.listed(priorList.stdout, targetDir, options.scope);
|
|
143
212
|
if (registered(priorEntry)) {
|
|
144
213
|
return {
|
|
145
214
|
status: 'registered', executable: 'clio-coder', results,
|
|
146
|
-
...(priorEntry.enabled === false ? { notice: disabledNotice(
|
|
215
|
+
...(priorEntry.enabled === false ? { notice: disabledNotice(pkg, options.scope) } : {})
|
|
147
216
|
};
|
|
148
217
|
}
|
|
149
218
|
|
|
@@ -152,7 +221,7 @@ function activateClio(targetDir, native, suppliedOptions) {
|
|
|
152
221
|
// until the receipt is durable lets a failed registration put the previous
|
|
153
222
|
// installation back before the file transaction rolls it back.
|
|
154
223
|
const staging = fs.mkdtempSync(path.join(path.dirname(root), '.wtfp-staged-'));
|
|
155
|
-
const source = path.join(staging,
|
|
224
|
+
const source = path.join(staging, pkg.id);
|
|
156
225
|
fs.renameSync(root, source);
|
|
157
226
|
let finished = false;
|
|
158
227
|
|
|
@@ -163,15 +232,15 @@ function activateClio(targetDir, native, suppliedOptions) {
|
|
|
163
232
|
if (!sameTree(publishedFiles, treeFiles(root))) {
|
|
164
233
|
throw new Error('Clio content changed concurrently; recovery tree preserved');
|
|
165
234
|
}
|
|
166
|
-
const removal = execute('clio-coder', [
|
|
235
|
+
const removal = execute('clio-coder', [pkg.command, 'remove', pkg.id, `--${options.scope}`, '--json'], environment,
|
|
167
236
|
{ ...options, allowAlreadyAbsent: true });
|
|
168
237
|
results.push(removal);
|
|
169
238
|
if (removal.status === 'unavailable') throw new Error('Clio became unavailable during rollback');
|
|
170
239
|
}
|
|
171
240
|
if (fs.existsSync(root)) throw new Error('Clio rollback did not remove the replacement');
|
|
172
|
-
const after = execute('clio-coder',
|
|
241
|
+
const after = execute('clio-coder', pkg.list(options.scope), environment, options);
|
|
173
242
|
results.push(after);
|
|
174
|
-
if (after.status === 'unavailable' ||
|
|
243
|
+
if (after.status === 'unavailable' || pkg.listed(after.stdout, targetDir, options.scope)) {
|
|
175
244
|
throw new Error('Clio rollback did not clear the replacement registration');
|
|
176
245
|
}
|
|
177
246
|
fs.renameSync(source, root);
|
|
@@ -184,22 +253,22 @@ function activateClio(targetDir, native, suppliedOptions) {
|
|
|
184
253
|
}
|
|
185
254
|
|
|
186
255
|
try {
|
|
187
|
-
const installation = execute('clio-coder', [
|
|
256
|
+
const installation = execute('clio-coder', [pkg.command, 'install', source, `--${options.scope}`, '--json'], environment, options);
|
|
188
257
|
results.push(installation);
|
|
189
258
|
if (installation.status === 'unavailable') throw new Error('Clio became unavailable during installation');
|
|
190
|
-
const inspected = execute('clio-coder',
|
|
259
|
+
const inspected = execute('clio-coder', pkg.verify(options.scope), environment, options);
|
|
191
260
|
results.push(inspected);
|
|
192
261
|
if (inspected.status === 'unavailable') throw new Error('Clio became unavailable during verification');
|
|
193
|
-
const entry =
|
|
262
|
+
const entry = pkg.verified(inspected.stdout, targetDir, options.scope);
|
|
194
263
|
if (!registered(entry) || !sameTree(publishedFiles, treeFiles(root))) {
|
|
195
|
-
throw new Error(
|
|
264
|
+
throw new Error(`Clio did not report the exact WTF-P ${pkg.noun} as installed and valid with zero diagnostics`);
|
|
196
265
|
}
|
|
197
266
|
if (priorEntry && priorEntry.enabled !== entry.enabled) {
|
|
198
|
-
throw new Error(
|
|
267
|
+
throw new Error(`Clio installation changed the existing WTF-P ${pkg.noun} enabled preference`);
|
|
199
268
|
}
|
|
200
269
|
return {
|
|
201
270
|
status: 'registered', executable: 'clio-coder', results, rollback,
|
|
202
|
-
...(entry.enabled === false ? { notice: disabledNotice(
|
|
271
|
+
...(entry.enabled === false ? { notice: disabledNotice(pkg, options.scope) } : {}),
|
|
203
272
|
commit() {
|
|
204
273
|
// Only the private held copy is removed; Clio owns its installed tree.
|
|
205
274
|
finished = true;
|
|
@@ -217,27 +286,49 @@ function activateClio(targetDir, native, suppliedOptions) {
|
|
|
217
286
|
}
|
|
218
287
|
}
|
|
219
288
|
|
|
289
|
+
// Remove the extension, then the plugin, each only when the receipt proves it.
|
|
290
|
+
// `ownedFiles` maps receipt paths below the target to their published hashes.
|
|
220
291
|
function deactivateClio(targetDir, native, suppliedOptions) {
|
|
221
292
|
const options = scopeOptions(targetDir, suppliedOptions);
|
|
293
|
+
const removed = [];
|
|
294
|
+
for (const pkg of clioPackages(native).reverse()) {
|
|
295
|
+
const prefix = `${pkg.source}/`;
|
|
296
|
+
const ownedFiles = options.ownedFiles && new Map([...options.ownedFiles]
|
|
297
|
+
.filter(([file]) => file.startsWith(prefix))
|
|
298
|
+
.map(([file, hash]) => [file.slice(prefix.length), hash]));
|
|
299
|
+
const result = deactivatePackage(targetDir, pkg, { ...options, ownedFiles });
|
|
300
|
+
if (result.status === 'unavailable') return result;
|
|
301
|
+
removed.push(result);
|
|
302
|
+
}
|
|
303
|
+
if (removed.length === 1) return removed[0];
|
|
304
|
+
const deferred = removed.find(result => result.status === 'deferred');
|
|
305
|
+
const results = removed.flatMap(result => result.results);
|
|
306
|
+
if (deferred) return { status: 'deferred', reason: deferred.reason, results };
|
|
307
|
+
return removed.some(result => result.status === 'unregistered')
|
|
308
|
+
? { status: 'unregistered', executable: 'clio-coder', results }
|
|
309
|
+
: { status: 'not-required', results };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function deactivatePackage(targetDir, pkg, options) {
|
|
222
313
|
const { execute, environment } = options;
|
|
223
314
|
const guard = createTargetGuard(targetDir);
|
|
224
|
-
const listing = execute('clio-coder',
|
|
315
|
+
const listing = execute('clio-coder', pkg.list(options.scope), environment, options);
|
|
225
316
|
if (listing.status === 'unavailable') return { status: 'unavailable', executable: 'clio-coder', results: [] };
|
|
226
|
-
if (!
|
|
317
|
+
if (!pkg.listed(listing.stdout, targetDir, options.scope)) {
|
|
227
318
|
return { status: 'not-required', results: [listing] };
|
|
228
319
|
}
|
|
229
320
|
|
|
230
321
|
// Native removal is recursive. Run it only when the receipt proves that every
|
|
231
322
|
// file below the installed root is one WTF-P published and nobody changed.
|
|
232
|
-
const root = resolveOwnedPath(targetDir,
|
|
323
|
+
const root = resolveOwnedPath(targetDir, pkg.source, guard);
|
|
233
324
|
const ownedFiles = options.ownedFiles;
|
|
234
325
|
if (!ownedFiles || !sameTree(treeFiles(root), ownedFiles)) {
|
|
235
|
-
return { status: 'deferred', reason:
|
|
326
|
+
return { status: 'deferred', reason: `Clio native removal would include unowned or modified ${pkg.noun} files`, results: [listing] };
|
|
236
327
|
}
|
|
237
|
-
const result = execute('clio-coder', [
|
|
328
|
+
const result = execute('clio-coder', [pkg.command, 'remove', pkg.id, `--${options.scope}`, '--json'], environment, options);
|
|
238
329
|
if (result.status === 'unavailable') return { status: 'unavailable', executable: 'clio-coder', results: [listing] };
|
|
239
|
-
const after = execute('clio-coder',
|
|
240
|
-
if (after.status === 'unavailable' || fs.existsSync(root) ||
|
|
330
|
+
const after = execute('clio-coder', pkg.list(options.scope), environment, options);
|
|
331
|
+
if (after.status === 'unavailable' || fs.existsSync(root) || pkg.listed(after.stdout, targetDir, options.scope)) {
|
|
241
332
|
throw new Error('Clio removal did not clear WTF-P content and registration');
|
|
242
333
|
}
|
|
243
334
|
return { status: 'unregistered', executable: 'clio-coder', results: [listing, result, after] };
|
package/bin/lib/manifest.js
CHANGED
|
@@ -67,8 +67,9 @@ const MANIFEST = {
|
|
|
67
67
|
source: 'marketplaces/wtfp'
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
|
-
// Clio consumes the canonical Agent Plugins bundle through its
|
|
71
|
-
// lifecycle
|
|
70
|
+
// Clio consumes the canonical Agent Plugins bundle through its plugin
|
|
71
|
+
// lifecycle and the desk through its extension lifecycle: two packages, two
|
|
72
|
+
// Clio installs, one WTF-P receipt.
|
|
72
73
|
clio: {
|
|
73
74
|
name: 'Clio Coder',
|
|
74
75
|
configDirEnv: 'CLIO_CODER_CONFIG_DIR',
|
|
@@ -80,6 +81,12 @@ const MANIFEST = {
|
|
|
80
81
|
src: path.join(ROOT, 'vendors', 'plugin'),
|
|
81
82
|
dest: 'plugins/wtfp',
|
|
82
83
|
type: 'dir'
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'extension',
|
|
87
|
+
src: path.join(ROOT, 'vendors', 'clio-extension'),
|
|
88
|
+
dest: 'extensions/wtfp',
|
|
89
|
+
type: 'dir'
|
|
83
90
|
}
|
|
84
91
|
],
|
|
85
92
|
discovery: {
|
|
@@ -89,7 +96,8 @@ const MANIFEST = {
|
|
|
89
96
|
native: {
|
|
90
97
|
kind: 'clio-plugin',
|
|
91
98
|
id: 'wtfp',
|
|
92
|
-
source: 'plugins/wtfp'
|
|
99
|
+
source: 'plugins/wtfp',
|
|
100
|
+
extension: { id: 'wtfp', source: 'extensions/wtfp' }
|
|
93
101
|
}
|
|
94
102
|
},
|
|
95
103
|
codex: {
|
package/bin/uninstall.js
CHANGED
|
@@ -780,9 +780,10 @@ async function uninstall(runtime, options, out) {
|
|
|
780
780
|
vendorConfig.native,
|
|
781
781
|
{ ...(vendorKey === 'clio' && plan.receipt.scope === 'project'
|
|
782
782
|
? { scope: 'project', cwd: path.dirname(targetDir) } : {}),
|
|
783
|
+
// Receipt paths below the target; Clio checks each package root against them.
|
|
783
784
|
ownedFiles: new Map(plan.items
|
|
784
|
-
.filter(item => item.
|
|
785
|
-
.map(item => [item.path
|
|
785
|
+
.filter(item => item.state === 'unchanged')
|
|
786
|
+
.map(item => [item.path, item.entry.sha256])) }
|
|
786
787
|
);
|
|
787
788
|
if (nativeRemoval.status === 'unavailable' && !options.hasQuiet) {
|
|
788
789
|
out.warn(`${nativeRemoval.executable} is unavailable; removing the WTF-P-owned staging files without changing the client's native registry.`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wtf-p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Portable, evidence-grounded academic writing workflows (papers, proposals, posters, presentations) for Clio Coder, Claude Code, Codex, GitHub Copilot CLI, OpenCode, Antigravity CLI, and Gemini CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"wtfp": "bin/install.js",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": "wtfp.generated-adapter/v1",
|
|
3
3
|
"generatorVersion": 5,
|
|
4
4
|
"target": "antigravity",
|
|
5
|
-
"sourceHash": "
|
|
5
|
+
"sourceHash": "c2e93ea50f26a53402f100fe9157834a3841748eebd8cc212648cd615738278d",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"path": "actions/add-todo.json",
|
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
"path": "plugin.json",
|
|
365
|
-
"sha256": "
|
|
365
|
+
"sha256": "9898153f5524eeea64715c41f2c6fe68f90a312e7f2c2ed08485a448da5ff989"
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"path": "project/README.md",
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "WTF-P evidence-grounded academic workflow plugin.",
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.8.0"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "wtfp",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Portable academic research and writing workflows.",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.8.0",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "akougkas"
|
|
18
18
|
},
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
"schema": "wtfp.generated-adapter/v1",
|
|
3
3
|
"generatorVersion": 5,
|
|
4
4
|
"target": "claude",
|
|
5
|
-
"sourceHash": "
|
|
5
|
+
"sourceHash": "21f3c778ba3384293f5b8d107edbda1d09b927b4c47550cd348ebc51c21921f9",
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"path": ".claude-plugin/marketplace.json",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "993e95f1576cf98d92e562f75ff126b6a2832f73ca27610de05145e802605f9c"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": ".claude-plugin/plugin.json",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "9b8391fc30f1b454b4795cb94c5de6b0ef6fb7accc1546221c3239f2b7ffeaae"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "actions/add-todo.json",
|
|
@@ -306,7 +306,7 @@
|
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
"path": "ai.iowarp.clio/prompts/wtfp/help.md",
|
|
309
|
-
"sha256": "
|
|
309
|
+
"sha256": "921118815b4cce6cac7a74388191265d56eeb68378096997f112f08de525a0e6"
|
|
310
310
|
},
|
|
311
311
|
{
|
|
312
312
|
"path": "ai.iowarp.clio/prompts/wtfp/insert-section.md",
|
|
@@ -574,7 +574,7 @@
|
|
|
574
574
|
},
|
|
575
575
|
{
|
|
576
576
|
"path": "plugin.json",
|
|
577
|
-
"sha256": "
|
|
577
|
+
"sha256": "5cd012f727ce4dfd33819323a828d78e64ca2a1d09e11e289dcb51648cb23502"
|
|
578
578
|
},
|
|
579
579
|
{
|
|
580
580
|
"path": "project/README.md",
|