toolaby 1.7.0 → 1.7.1
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 +1 -1
- package/bin.mjs +11 -6
- package/lib/summary.js +8 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The Toolaby command line. It puts the Wall — sign-in, a Free plan, paid plans, licences and subscriptions — into a Chrome extension you already have, or makes a new one for you.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npm i -g toolaby # once (or run every command through `npx -y toolaby@latest …`)
|
|
6
|
+
npm i -g toolaby # once (or run every command through `npx -y toolaby@latest …`); on Windows, type toolaby-cli
|
|
7
7
|
toolaby wire <tool-id> # in your extension's folder, on Test; signs you in first if it must
|
|
8
8
|
toolaby wire <tool-id> --live # the same, on Live: the store build
|
|
9
9
|
```
|
package/bin.mjs
CHANGED
|
@@ -38,13 +38,13 @@ import { homedir } from 'node:os';
|
|
|
38
38
|
import { spawn } from 'node:child_process';
|
|
39
39
|
import { createHmac, randomBytes } from 'node:crypto';
|
|
40
40
|
import { wireManifest, drawsItself, WORKER_LINES, wallWorkerSource, configValues, wrappedBy, namedWorker as workerIn, startsPlatform as startsWall, CLASSIC_CLIENT } from './lib/manifest.js';
|
|
41
|
-
import { wiringSummary, popupSwapIn, ownCode } from './lib/summary.js';
|
|
41
|
+
import { wiringSummary, popupSwapIn, gatesIn, ownCode } from './lib/summary.js';
|
|
42
42
|
import { detectProject, CODE_FILES, POPUP_FILES, SIDE_PANEL_FILES, filesToWrite, fillPages, scaffoldManifest, scaffoldFilesFor, surfacesOf, hasPopup, hasSidePanel, SURFACES, STALE_FILES, BUILD_COPY_NOTE, AGENT_FILES, AGENT_ENTRY_FILES } from './lib/project.js';
|
|
43
43
|
import { runMcp } from './lib/mcp.js';
|
|
44
44
|
import { runCheck } from './lib/check.js';
|
|
45
45
|
import { inside, signInPage, devicePolling, opener, privateKind, privateContent, privateCopies, googleKey, projectRoot, gitDirectory, gitObject, gitObjects, gitFile, notAnImage, unpacked, COMPRESSED, publicLinks, privateLinks, oneLine, fetchBounded, fetchHere, readBounded, readText, SCAFFOLD_FILES } from './lib/safe.js';
|
|
46
46
|
|
|
47
|
-
const VERSION = '1.7.
|
|
47
|
+
const VERSION = '1.7.1';
|
|
48
48
|
const CLIENT_ID = 'toolaby-cli';
|
|
49
49
|
const argv = process.argv.slice(2);
|
|
50
50
|
// `--version` and `--help` are commands of their own; every other command is the first bare word.
|
|
@@ -297,9 +297,16 @@ async function wire() {
|
|
|
297
297
|
const oldConfig = existsSync(configPath) ? readOr(configPath, '') : '';
|
|
298
298
|
const remembered = oldConfig.match(/appPopup:\s*'([^']*)'/)?.[1] || null;
|
|
299
299
|
const rememberedSidePanel = oldConfig.match(/appSidePanel:\s*'([^']*)'/)?.[1] || null;
|
|
300
|
+
// The extension's own code, read first: a popup it handles itself (setPopup, getPopup) decides which page stands in
|
|
301
|
+
// front, and whether it opens the paywall anywhere decides whether the lines for it are a step.
|
|
302
|
+
const code = project.manifestFile ? [...tree].filter(ownCode).slice(0, 400).map((path) => { let text = ''; try { if (statSync(join(dir, path)).size < 512_000) text = readOr(join(dir, path), ''); } catch { /* gone */ } return { path, text }; }) : [];
|
|
303
|
+
const popupSwap = popupSwapIn(code);
|
|
304
|
+
// Wired for the first time, an extension whose code handles its popup keeps it in front: the Wall's in front of it is
|
|
305
|
+
// skipped by setPopup(), and found by getPopup() where the code expects its own (Chrome's action sample threw so).
|
|
306
|
+
const keptForSwap = !oldConfig && !!popupSwap && typeof manifest?.action?.default_popup === 'string' && !flag('--own-popup');
|
|
300
307
|
// An extension whose own pages draw the panel — what `create` makes, "your popup first", or asked with --own-popup —
|
|
301
308
|
// keeps them in front.
|
|
302
|
-
const ownInFront = flag('--own-popup') || drawsItself(manifest, oldConfig);
|
|
309
|
+
const ownInFront = flag('--own-popup') || drawsItself(manifest, oldConfig) || keptForSwap;
|
|
303
310
|
// The background the manifest names, read from inside the folder only: whether it starts the Wall, or is the Wall's.
|
|
304
311
|
const namedWorker = workerIn(manifest) ?? '';
|
|
305
312
|
const workerSource = namedWorker && has(namedWorker) && !inside(dir, namedWorker).why ? readOr(join(dir, namedWorker), '') : null;
|
|
@@ -344,9 +351,7 @@ async function wire() {
|
|
|
344
351
|
} else if (project.createWorker) {
|
|
345
352
|
write(project.createWorker.file, project.createWorker.content);
|
|
346
353
|
}
|
|
347
|
-
|
|
348
|
-
const code = appPopup ? [...tree].filter(ownCode).slice(0, 400).map((path) => { let text = ''; try { if (statSync(join(dir, path)).size < 512_000) text = readOr(join(dir, path), ''); } catch { /* gone */ } return { path, text }; }) : [];
|
|
349
|
-
const summary = wiringSummary({ project, wiring, appPopup, appSidePanel, workerStarts: !!project.worker && startsPlatform(join(dir, project.worker)), popupSwap: popupSwapIn(code) });
|
|
354
|
+
const summary = wiringSummary({ project, wiring, appPopup, appSidePanel, workerStarts: !!project.worker && startsPlatform(join(dir, project.worker)), popupSwap, keptForSwap, gates: project.manifestFile ? gatesIn(code) : null });
|
|
350
355
|
|
|
351
356
|
// Wired again, a folder takes `upgrade` (wire, replacing the platform's files): the command, ready to paste.
|
|
352
357
|
const into = opt('--into');
|
package/lib/summary.js
CHANGED
|
@@ -9,6 +9,8 @@ export function popupSwapIn(files) {
|
|
|
9
9
|
}
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
|
+
/** Whether the extension's own code opens the paywall anywhere: gate() or showPaywall(), outside its comments. */
|
|
13
|
+
export const gatesIn = (files) => files.some((f) => /\btoolaby\s*\.\s*(gate|showPaywall)\s*\(/.test(withoutComments(f.text)));
|
|
12
14
|
/** Whether a path is the extension's own code, for popupSwapIn: a script, not the Wall's, not a dependency's or a build's. */
|
|
13
15
|
export const ownCode = (path) => /\.(m?js|jsx|ts|tsx)$/.test(path) && !/(^|\/)toolaby[^/]*$/.test(path) && !/(^|\/)(node_modules|dist|build|\.output|\.wxt|\.plasmo)\//.test(path);
|
|
14
16
|
export function wiringSummary(o) {
|
|
@@ -21,6 +23,8 @@ export function wiringSummary(o) {
|
|
|
21
23
|
? { tone: 'warn', label: 'Popup', text: `Your code handles the popup itself (${o.popupSwap.call} in ${o.popupSwap.file}), so keep yours in front`, fix: 'own-popup' }
|
|
22
24
|
: { tone: 'ok', label: 'Popup', text: `The Wall checks first, then opens ${o.appPopup}` });
|
|
23
25
|
}
|
|
26
|
+
else if (ownPopup && o.keptForSwap && o.popupSwap)
|
|
27
|
+
rows.push({ tone: 'ok', label: 'Popup', text: `Yours stays in front, as your code handles it (${o.popupSwap.call} in ${o.popupSwap.file})` });
|
|
24
28
|
else if (ownPopup)
|
|
25
29
|
rows.push({ tone: 'ok', label: 'Popup', text: `Yours stays in front; toolaby.showPaywall() opens the Wall's` });
|
|
26
30
|
else if (p.note)
|
|
@@ -55,6 +59,10 @@ export function wiringSummary(o) {
|
|
|
55
59
|
rows.push({ tone: 'todo', label: 'Background', text: `Add these 2 lines to the top of ${p.worker}:`, code: p.workerLines.trim() });
|
|
56
60
|
else if (p.worker)
|
|
57
61
|
rows.push({ tone: 'ok', label: 'Background', text: `${p.worker} starts the Wall` });
|
|
62
|
+
// With no page of the Wall's in front, the paywall opens only where the code asks for it: when nothing does, the lines.
|
|
63
|
+
if (!o.appPopup && !o.appSidePanel && o.gates === false && p.kind === 'plain') {
|
|
64
|
+
rows.push({ tone: 'todo', label: 'Paywall', text: p.built ? 'Nothing opens it yet. Where your paid action starts, add (the import is the path to toolaby.js):' : 'Nothing opens it yet. Where your paid action starts, in a module script, add:', code: `import { toolaby } from '${p.built ? './toolaby.js' : '/toolaby.js'}';\n\nconst permit = await toolaby.gate();\nif (!permit.allowed) return toolaby.showPaywall(permit);` });
|
|
65
|
+
}
|
|
58
66
|
// The manifest: what it gained, or, generated by a framework, what its config needs.
|
|
59
67
|
if (w)
|
|
60
68
|
rows.push({ tone: 'ok', label: 'Manifest', text: w.added.length ? w.added.join(' · ') : 'Has what the Wall needs' });
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolaby",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "The Toolaby command line: sign in once, then wire any Chrome extension to your tool on the Wall — sign-in, the Free plan, licences and subscriptions — or start a new one; check it, and give coding agents the Wall as an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
+
"toolaby-cli": "bin.mjs",
|
|
7
8
|
"toolaby": "bin.mjs"
|
|
8
9
|
},
|
|
9
10
|
"files": [
|