@tommy-ca/lazypi 0.7.0 → 0.8.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 +15 -6
- package/bin/lazypi.mjs +28 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ LazyPi will:
|
|
|
13
13
|
1. Install `pi` for you if it isn't installed yet.
|
|
14
14
|
2. Ask if you want to install all the packages or choose which to install.
|
|
15
15
|
|
|
16
|
-
That setup is the harness core — isolated sub-agents, a structured ask gate, skill visibility, $ skill mention, a long-objective gate, side chat, context budgeting, code simplification review, web research, and
|
|
16
|
+
That setup is the harness core — isolated sub-agents, a structured ask gate, skill visibility, $ skill mention, a long-objective gate, side chat, context budgeting, code simplification review, web research, FFF search, a workflow engine for sub-agent fan-out, and ponytail discipline review. Optional extras (skill arguments, memory, MCP, interactive shell overlays, research loops, themes) install on demand with `pi install`.
|
|
17
17
|
|
|
18
18
|
That's it. Once done - run `pi` and experience a feature rich coding agent experience.
|
|
19
19
|
|
|
@@ -54,11 +54,20 @@ There is nothing to "uninstall" for LazyPi itself — `npx` doesn't leave it aro
|
|
|
54
54
|
|
|
55
55
|
Run the built-in health check with `npx @tommy-ca/lazypi doctor`.
|
|
56
56
|
|
|
57
|
-
**Stale
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
**Stale cached run after a release?** Both runners cache resolved versions: `bunx`
|
|
58
|
+
serves from its package cache and `npx` reuses the extracted copy in
|
|
59
|
+
`~/.npm/_npx`, so a bare `npx @tommy-ca/lazypi` / `bunx @tommy-ca/lazypi` can
|
|
60
|
+
keep serving the previous release until the cache is cleared. Run
|
|
61
|
+
`bun pm cache rm` (and/or delete the stale `~/.npm/_npx` entry), pin
|
|
62
|
+
`@tommy-ca/lazypi@latest`, and check `npx @tommy-ca/lazypi --version` to see
|
|
63
|
+
which release is actually running.
|
|
64
|
+
|
|
65
|
+
**`lazypi: not found` when running npx inside the LazyPi repo?** npm exec
|
|
66
|
+
matches the spec against the local tree, and the checkout itself is
|
|
67
|
+
`@tommy-ca/lazypi@<version>` — so it skips the npx install and tries to run
|
|
68
|
+
`lazypi` from `./node_modules/.bin`, which never exists for the project's own
|
|
69
|
+
name. Run npx from any other directory (e.g. `~`); bunx and pinned-version
|
|
70
|
+
specs behave the same way, so `cd` out of the checkout first.
|
|
62
71
|
|
|
63
72
|
## Site / docs
|
|
64
73
|
|
package/bin/lazypi.mjs
CHANGED
|
@@ -26,24 +26,25 @@ import {
|
|
|
26
26
|
const CATEGORIES = ["core"];
|
|
27
27
|
|
|
28
28
|
export const PACKAGES = [
|
|
29
|
-
{ id: "subagents", category: "core", source: "npm:pi-subagents",
|
|
30
|
-
{ id: "pi-ask-user", category: "core", source: "npm:pi-ask-user",
|
|
31
|
-
{ id: "pi-skillful", category: "core", source: "npm:pi-skillful",
|
|
32
|
-
{ id: "mention-skill", category: "core", source: "npm:@zigai/pi-mention-skill",
|
|
33
|
-
{ id: "goal", category: "core", source: "npm:@narumitw/pi-goal",
|
|
29
|
+
{ id: "subagents", category: "core", source: "npm:pi-subagents", description: "Sub-agent execution", hint: "Run isolated sub-agents for parallel work." },
|
|
30
|
+
{ id: "pi-ask-user", category: "core", source: "npm:pi-ask-user", description: "Ask-user prompts", hint: "Interactive user questions for agent workflows." },
|
|
31
|
+
{ id: "pi-skillful", category: "core", source: "npm:pi-skillful", description: "Skill visibility", hint: "Discover skills above the git root, hide unused skills, and expand /skill:name inline." },
|
|
32
|
+
{ id: "mention-skill", category: "core", source: "npm:@zigai/pi-mention-skill", description: "$ skill mention", hint: "Fuzzy-search skills with $ and expand them into the prompt; hidden skills stay reachable." },
|
|
33
|
+
{ id: "goal", category: "core", source: "npm:@narumitw/pi-goal", description: "Long-objective gate", hint: "Stop on done, blocked, or external wait for long tasks." },
|
|
34
34
|
{
|
|
35
35
|
id: "btw",
|
|
36
36
|
category: "core",
|
|
37
37
|
source: "npm:@narumitw/pi-btw",
|
|
38
38
|
legacySources: ["npm:pi-btw"],
|
|
39
|
-
essential: true,
|
|
40
39
|
description: "Side-chat popover",
|
|
41
40
|
hint: "Ask quick questions without polluting your conversation history.",
|
|
42
41
|
},
|
|
43
|
-
{ id: "context-usage", category: "core", source: "npm:pi-context-usage",
|
|
44
|
-
{ id: "simplify", category: "core", source: "npm:pi-simplify",
|
|
45
|
-
{ id: "web-access", category: "core", source: "npm:pi-web-access",
|
|
46
|
-
{ id: "fff", category: "core", source: "npm:@ff-labs/pi-fff",
|
|
42
|
+
{ id: "context-usage", category: "core", source: "npm:pi-context-usage", description: "Context budget", hint: "See what is burning the context window before it fills." },
|
|
43
|
+
{ id: "simplify", category: "core", source: "npm:pi-simplify", description: "Code simplify review", hint: "Reviews recently changed code for clarity, consistency, and maintainability." },
|
|
44
|
+
{ id: "web-access", category: "core", source: "npm:pi-web-access", description: "Web search and page fetch", hint: "Built-in web search and URL fetching." },
|
|
45
|
+
{ id: "fff", category: "core", source: "npm:@ff-labs/pi-fff", description: "FFF fuzzy search", hint: "Additive fffind / ffgrep / fff-multi-grep beside the built-in tools; /fff-health checks the index." },
|
|
46
|
+
{ id: "dynamic-workflows", category: "core", source: "npm:@quintinshaw/pi-dynamic-workflows", description: "Workflow engine", hint: "Fan work out across subagents: /workflows TUI, deep-research, resume, token accounting." },
|
|
47
|
+
{ id: "ponytail", category: "core", source: "npm:@dietrichgebert/ponytail", description: "Lazy senior dev mode", hint: "Enforces minimal, stdlib-first code; /ponytail review, audit, and a debt ledger." },
|
|
47
48
|
];
|
|
48
49
|
|
|
49
50
|
// ---------------------------------------------------------------------------
|
|
@@ -196,7 +197,7 @@ ${bold("Default behaviour:")}
|
|
|
196
197
|
- With --yes, --only, or --except the picker is skipped.
|
|
197
198
|
|
|
198
199
|
${bold("Categories:")}
|
|
199
|
-
core the harness control plane: sub-agents, ask gate, skill visibility, $ mention, goal, side chat, context budget, simplify, web research, fff search
|
|
200
|
+
core the harness control plane: sub-agents, workflows, ask gate, skill visibility, $ mention, goal, side chat, context budget, simplify, web research, fff search, ponytail discipline
|
|
200
201
|
Non-catalog extras (pi install npm:<source>): skill-args, memory, mcp,
|
|
201
202
|
interactive-shell, ralph-wiggum, curated-themes (65 dark themes)
|
|
202
203
|
|
|
@@ -313,11 +314,6 @@ function readInstalledSources(local) {
|
|
|
313
314
|
return { sources, path: current.path, exists: true };
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
function runPi(args) {
|
|
317
|
-
const result = spawnCommand("pi", args, { stdio: "inherit" });
|
|
318
|
-
return result.status ?? 1;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
317
|
function commandPath(name) {
|
|
322
318
|
const command = platform() === "win32" ? "where" : "which";
|
|
323
319
|
const probe = spawnCommand(command, [name], { encoding: "utf8" });
|
|
@@ -330,8 +326,15 @@ function legacySourcesForPackage(pkg) {
|
|
|
330
326
|
return Array.isArray(pkg.legacySources) ? pkg.legacySources : [];
|
|
331
327
|
}
|
|
332
328
|
|
|
329
|
+
// An installed source matches a catalog source when equal or when it is the
|
|
330
|
+
// same source with a version/pin suffix (npm:pkg vs npm:pkg@x.y.z,
|
|
331
|
+
// git:... vs git:...@sha).
|
|
332
|
+
export function sourcesMatch(catalogSource, installedSource) {
|
|
333
|
+
return catalogSource === installedSource || installedSource.startsWith(`${catalogSource}@`);
|
|
334
|
+
}
|
|
335
|
+
|
|
333
336
|
function isLegacySourceForPackage(pkg, source) {
|
|
334
|
-
return legacySourcesForPackage(pkg).
|
|
337
|
+
return legacySourcesForPackage(pkg).some((legacy) => sourcesMatch(legacy, source));
|
|
335
338
|
}
|
|
336
339
|
|
|
337
340
|
function findLegacyInstalledSources(pkg, installedPiSources) {
|
|
@@ -352,10 +355,11 @@ function removeLegacy(pkg, installedPiSources, local, interactive) {
|
|
|
352
355
|
|
|
353
356
|
function packageInstallStatus(pkg, installedPiSources) {
|
|
354
357
|
const legacySources = findLegacyInstalledSources(pkg, installedPiSources);
|
|
358
|
+
const installed = [...installedPiSources].some((src) => sourcesMatch(pkg.source, src));
|
|
355
359
|
return {
|
|
356
|
-
installed
|
|
360
|
+
installed,
|
|
357
361
|
legacy: legacySources.length > 0,
|
|
358
|
-
present:
|
|
362
|
+
present: installed || legacySources.length > 0,
|
|
359
363
|
};
|
|
360
364
|
}
|
|
361
365
|
|
|
@@ -694,11 +698,12 @@ function cmdStatus(flags) {
|
|
|
694
698
|
return 1;
|
|
695
699
|
}
|
|
696
700
|
|
|
697
|
-
const piCatalogSources = new Set(PACKAGES.flatMap((p) => [p.source, ...legacySourcesForPackage(p)]));
|
|
698
701
|
const installed = PACKAGES.filter((pkg) => packageInstallStatus(pkg, sources).installed);
|
|
699
702
|
const legacy = PACKAGES.filter((pkg) => packageInstallStatus(pkg, sources).legacy);
|
|
700
703
|
const missing = PACKAGES.filter((pkg) => !packageInstallStatus(pkg, sources).present);
|
|
701
|
-
const others = [...sources].filter(
|
|
704
|
+
const others = [...sources].filter(
|
|
705
|
+
(src) => !PACKAGES.some((pkg) => sourcesMatch(pkg.source, src) || isLegacySourceForPackage(pkg, src)),
|
|
706
|
+
);
|
|
702
707
|
|
|
703
708
|
printHeader(`Installed from LazyPi catalog (${installed.length}/${PACKAGES.length}):`);
|
|
704
709
|
if (installed.length === 0) console.log(dim(" none"));
|
|
@@ -740,7 +745,7 @@ async function cmdUpdate(flags) {
|
|
|
740
745
|
|
|
741
746
|
console.log(bold("pi update"));
|
|
742
747
|
|
|
743
|
-
return
|
|
748
|
+
return spawnCommand("pi", flags.local ? ["update", "--extensions"] : ["update"], { stdio: "inherit" }).status ?? 1;
|
|
744
749
|
}
|
|
745
750
|
|
|
746
751
|
// ---------------------------------------------------------------------------
|
|
@@ -853,7 +858,7 @@ async function cmdRemove(flags, targets) {
|
|
|
853
858
|
|
|
854
859
|
const sourcesToRemove = pkg
|
|
855
860
|
? [
|
|
856
|
-
...
|
|
861
|
+
...[...installedSources].filter((src) => sourcesMatch(pkg.source, src)),
|
|
857
862
|
...findLegacyInstalledSources(pkg, installedSources),
|
|
858
863
|
]
|
|
859
864
|
: [source];
|