@topce/pizx 0.4.0 → 0.5.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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  [![GitHub Sponsors](https://img.shields.io/github/sponsors/topce?style=social&logo=github)](https://github.com/sponsors/topce)
4
4
 
5
+ ![pizx — zx fork with native Pi AI integration](github-social-banner.png)
6
+
5
7
  > **zx fork with native Pi AI integration** — 15 template tags for shell scripting, AI text generation, coding agents, agentic patterns, communication, and orchestration topologies.
6
8
 
7
9
  ## Quick Start
@@ -46,7 +48,7 @@ npm install @topce/pizx
46
48
 
47
49
  **Prerequisites:**
48
50
  - Node.js >= 22.19.0
49
- - [Pi AI](https://github.com/earendil-works/pi-ai) installed and configured (`pi auth login`)
51
+ - [Pi AI](https://github.com/earendil-works/pi) installed and configured (`pi auth login`)
50
52
  - Shell commands from [zx](https://github.com/google/zx) (`$`, `cd`, `echo`, `fetch`, etc.)
51
53
 
52
54
  ## Writing Scripts
@@ -66,16 +68,25 @@ echo(intro)
66
68
  ```js
67
69
  import { $, π, Π, Ρ, Φ, Σ } from '@topce/pizx'
68
70
 
71
+ // Greek letters work everywhere...
69
72
  const output = await $`ls src/ | grep '.ts'`
70
73
  console.log(output.stdout)
71
74
 
72
75
  const review = await π`review this code for issues:\n${output.stdout}`
73
76
  console.log(review.text)
74
77
 
75
- // Use the coding agent to fix issues
76
- await Π`fix the TypeScript errors in src/`
78
+ // ...and so do English word aliases:
79
+ import { pi, Pi, ralph, fleet, subagent } from '@topce/pizx'
80
+
81
+ const answer = await pi`explain async/await`
82
+ await Pi`fix the TypeScript errors in src/`
83
+ await fleet`review all files in src/`
77
84
  ```
78
85
 
86
+ > **English word aliases**: Every Greek letter tag has an English alternative.
87
+ > `pi` (alias for `π`), `Pi` (alias for `Π`), `fleet` (alias for `Φ`), `ralph` (alias for `Ρ`),
88
+ > `pipeline` (alias for `Λ`), etc. — use whichever style you prefer. See [full mapping](#english-aliases) below.
89
+
79
90
  ### CLI Quick Queries
80
91
 
81
92
  ```bash
@@ -126,6 +137,24 @@ Each tag has detailed documentation in [`docs/`](docs/):
126
137
  | `Χ` | Chi | Analyze traces → extract patterns | [docs/chi.md](docs/chi.md) |
127
138
  | `Τ` | Tau | Define schema → write → refine → consolidate | [docs/tau.md](docs/tau.md) |
128
139
 
140
+ ### English Aliases
141
+
142
+ Every Greek letter tag has an equivalent English word. They're interchangeable — use whichever style you prefer.
143
+
144
+ | Greek | English | Greek | English |
145
+ |-------|---------|-------|---------|
146
+ | `π` | `pi` | `Π` | `Pi` |
147
+ | `Ρ` | `ralph` | `Φ` | `fleet` |
148
+ | `Σ` | `subagent` | `Δ` | `debate` |
149
+ | `Λ` | `pipeline` | `Ψ` | `critique` |
150
+ | `Ω` | `orchestrator` | `Ν` | `team` |
151
+ | `Θ` | `thread` | `Μ` | `memory` |
152
+ | `Β` | `broadcast` | `Α` | `adaptive` |
153
+ | `Γ` | `graph` | `Χ` | `learn` |
154
+ | `Τ` | `store` | | |
155
+
156
+ See [`english-examples/`](english-examples/) for runnable examples using all English aliases.
157
+
129
158
  ## Architecture
130
159
 
131
160
  See [docs/decisions/](docs/decisions/) for Architecture Decision Records covering the key design choices:
@@ -395,3 +424,10 @@ See [`examples/`](examples/) for runnable examples of every pattern and feature:
395
424
  ## License
396
425
 
397
426
  MIT
427
+
428
+ ## Credits
429
+
430
+ Built on the shoulders of two outstanding tools:
431
+
432
+ - [**zx**](https://github.com/google/zx) by [Anton Medvedev](https://github.com/antonmedv) — the original shell scripting tool for Node.js that popularized template-tag ergonomics for command execution. pizx preserves every zx API (`$`, `cd`, `echo`, `fetch`, `chalk`, etc.) unchanged.
433
+ - [**Pi**](https://github.com/earendil-works/pi) by Mario Zechner / Earendil Works — the unified LLM API and coding agent harness that powers all `π`, `Π`, and pattern tags through `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent`.
package/dist/cli.js CHANGED
@@ -367,7 +367,8 @@ ${skillContext}` : skillContext;
367
367
  reasoning: opts.thinkingLevel ?? "medium",
368
368
  thinkingBudgets: opts.thinkingBudgets,
369
369
  timeoutMs: opts.timeoutMs,
370
- maxRetries: opts.maxRetries
370
+ maxRetries: opts.maxRetries,
371
+ apiKey: opts.apiKey
371
372
  }
372
373
  );
373
374
  const durationMs = Date.now() - t0;
@@ -904,9 +905,9 @@ var defaults4 = {
904
905
  rounds: 1
905
906
  };
906
907
  var CritiqueRound = class {
907
- constructor(content, critique, round) {
908
+ constructor(content, critique2, round) {
908
909
  this.content = content;
909
- this.critique = critique;
910
+ this.critique = critique2;
910
911
  this.round = round;
911
912
  }
912
913
  content;
@@ -970,12 +971,12 @@ Revise the content based on the critique.`,
970
971
  }
971
972
  if (!opts.quiet) process.stderr.write(` \u2192 Critiquing (round ${r + 1})...
972
973
  `);
973
- const critique = await ask(currentContent, {
974
+ const critique2 = await ask(currentContent, {
974
975
  ...opts,
975
976
  model: plannerModel,
976
977
  system: mergeSystem(opts.system, CRITIQUE_SYSTEM)
977
978
  });
978
- critiqueRounds.push(new CritiqueRound(currentContent, critique, r));
979
+ critiqueRounds.push(new CritiqueRound(currentContent, critique2, r));
979
980
  }
980
981
  const t1 = Date.now();
981
982
  const finalContent = currentContent;
@@ -2461,21 +2462,21 @@ ${prompt}`, {
2461
2462
  }
2462
2463
  return { keys, roles: roles.slice(0, agentCount), assignments };
2463
2464
  }
2464
- function formatStore(store) {
2465
- const entries = Object.entries(store).filter(([, v]) => v);
2465
+ function formatStore(store2) {
2466
+ const entries = Object.entries(store2).filter(([, v]) => v);
2466
2467
  if (entries.length === 0) return "(empty \u2014 you are the first contributor)";
2467
2468
  return entries.map(([k, v]) => `[${k}]: ${v}`).join("\n\n");
2468
2469
  }
2469
- function mergeEntry(store, key, content) {
2470
- if (store[key]) {
2471
- store[key] += `
2470
+ function mergeEntry(store2, key, content) {
2471
+ if (store2[key]) {
2472
+ store2[key] += `
2472
2473
 
2473
2474
  ${content}`;
2474
2475
  } else {
2475
- store[key] = content;
2476
+ store2[key] = content;
2476
2477
  }
2477
2478
  }
2478
- async function executeRound(roles, assignments, store, round, opts) {
2479
+ async function executeRound(roles, assignments, store2, round, opts) {
2479
2480
  const workerModel = opts.workerModel ?? opts.model;
2480
2481
  const isWrite = round === 1;
2481
2482
  const operation = isWrite ? "write" : "update";
@@ -2483,7 +2484,7 @@ async function executeRound(roles, assignments, store, round, opts) {
2483
2484
  roles.map(async (role) => {
2484
2485
  const assignedKeys = assignments.get(role) ?? ["General"];
2485
2486
  const keysStr = assignedKeys.join(", ");
2486
- const storeText = formatStore(store);
2487
+ const storeText = formatStore(store2);
2487
2488
  const systemPrompt = isWrite ? WRITE_SYSTEM(role, keysStr).replace("{store}", storeText) : UPDATE_SYSTEM(role, keysStr).replace("{store}", storeText);
2488
2489
  const task = isWrite ? `Write your initial findings to your assigned keys: ${keysStr}` : `Review the shared context and update your entries for keys: ${keysStr}`;
2489
2490
  const response = await ask(task, {
@@ -2495,7 +2496,7 @@ async function executeRound(roles, assignments, store, round, opts) {
2495
2496
  })
2496
2497
  );
2497
2498
  const entries = [];
2498
- const newStore = { ...store };
2499
+ const newStore = { ...store2 };
2499
2500
  for (const r of roundResults) {
2500
2501
  if (r.status !== "fulfilled") continue;
2501
2502
  const { role, response } = r.value;
@@ -2518,8 +2519,8 @@ async function executeRound(roles, assignments, store, round, opts) {
2518
2519
  }
2519
2520
  return { entries, store: newStore };
2520
2521
  }
2521
- async function consolidateStore(task, store, opts) {
2522
- const storeText = formatStore(store);
2522
+ async function consolidateStore(task, store2, opts) {
2523
+ const storeText = formatStore(store2);
2523
2524
  return ask(
2524
2525
  `Original task: ${task}
2525
2526
 
@@ -2560,7 +2561,7 @@ async function execute14(pieces, args, opts) {
2560
2561
  }
2561
2562
  }
2562
2563
  const allEntries = [];
2563
- let store = {};
2564
+ let store2 = {};
2564
2565
  for (let round = 1; round <= totalRounds; round++) {
2565
2566
  const label = round === 1 ? "Writing" : "Updating";
2566
2567
  if (!opts.quiet) process.stderr.write(` \u2192 Round ${round}/${totalRounds}: ${label}...
@@ -2568,15 +2569,15 @@ async function execute14(pieces, args, opts) {
2568
2569
  const { entries, store: updatedStore } = await executeRound(
2569
2570
  roles,
2570
2571
  assignments,
2571
- store,
2572
+ store2,
2572
2573
  round,
2573
2574
  opts
2574
2575
  );
2575
2576
  allEntries.push(...entries);
2576
- store = updatedStore;
2577
+ store2 = updatedStore;
2577
2578
  }
2578
2579
  if (!opts.quiet) process.stderr.write(" \u2192 Consolidating store...\n");
2579
- const synthesis = await consolidateStore(task, store, { ...opts, plannerModel });
2580
+ const synthesis = await consolidateStore(task, store2, { ...opts, plannerModel });
2580
2581
  if (!opts.quiet && opts.qualityCheck) process.stderr.write(" \u2192 Quality review...\n");
2581
2582
  const qualityReview = await runQualityReview(task, synthesis, opts);
2582
2583
  const t1 = Date.now();
@@ -2587,7 +2588,7 @@ async function execute14(pieces, args, opts) {
2587
2588
  `Entries: ${allEntries.length}`,
2588
2589
  `Synthesis: ${synthesis}`
2589
2590
  ].join("\n\n");
2590
- return new TauOutput(summary, allEntries, store, synthesis, t0, t1, qualityReview);
2591
+ return new TauOutput(summary, allEntries, store2, synthesis, t0, t1, qualityReview);
2591
2592
  }
2592
2593
  var \u03A4 = createPatternTag(defaults14, execute14);
2593
2594
 
@@ -2628,10 +2629,10 @@ The conversation so far:
2628
2629
  Respond as your role. Be specific, build on or challenge what others have said.
2629
2630
  Keep your response under 200 words.`;
2630
2631
  var SYNTHESIS_SYSTEM6 = `You are a neutral facilitator. Synthesize the multi-agent conversation thread into a clear, actionable conclusion. Weigh the evidence, resolve conflicts, and present the best path forward.`;
2631
- function buildThreadPrompt(role, thread) {
2632
+ function buildThreadPrompt(role, thread2) {
2632
2633
  return THREAD_PROMPT.replace("{role}", role).replace(
2633
2634
  "{thread}",
2634
- thread || "(This is the first message in the thread.)"
2635
+ thread2 || "(This is the first message in the thread.)"
2635
2636
  );
2636
2637
  }
2637
2638
  async function execute15(pieces, args, opts) {
@@ -2649,17 +2650,17 @@ async function execute15(pieces, args, opts) {
2649
2650
  `);
2650
2651
  }
2651
2652
  const messages = [];
2652
- let thread = `Topic: ${topic}
2653
+ let thread2 = `Topic: ${topic}
2653
2654
  `;
2654
2655
  for (let turn = 1; turn <= maxTurns; turn++) {
2655
2656
  if (!opts.quiet) process.stderr.write(` \u2192 Turn ${turn}/${maxTurns}
2656
2657
  `);
2657
2658
  for (let a = 0; a < roles.length; a++) {
2658
2659
  const role = roles[a] ?? `Agent ${a + 1}`;
2659
- const prompt = buildThreadPrompt(role, thread);
2660
+ const prompt = buildThreadPrompt(role, thread2);
2660
2661
  const response = await ask(prompt, { ...opts, model: workerModel });
2661
2662
  messages.push(new ThreadMessage(role, turn, response));
2662
- thread += `
2663
+ thread2 += `
2663
2664
  [${role}] (Turn ${turn}): ${response}
2664
2665
  `;
2665
2666
  }
@@ -2669,7 +2670,7 @@ async function execute15(pieces, args, opts) {
2669
2670
  `Topic: ${topic}
2670
2671
 
2671
2672
  Conversation thread:
2672
- ${thread}
2673
+ ${thread2}
2673
2674
 
2674
2675
  Synthesize a clear, actionable conclusion.`,
2675
2676
  {
@@ -2689,6 +2690,23 @@ Synthesize a clear, actionable conclusion.`,
2689
2690
  }
2690
2691
  var \u0398 = createPatternTag(defaults15, execute15);
2691
2692
 
2693
+ // src/patterns/index.ts
2694
+ var ralph = \u03A1;
2695
+ var fleet = \u03A6;
2696
+ var subagent = \u03A3;
2697
+ var debate = \u0394;
2698
+ var pipeline = \u039B;
2699
+ var critique = \u03A8;
2700
+ var orchestrator = \u03A9;
2701
+ var thread = \u0398;
2702
+ var memory = \u039C;
2703
+ var broadcast = \u0392;
2704
+ var adaptive = \u0391;
2705
+ var graph = \u0393;
2706
+ var team = \u039D;
2707
+ var learn = \u03A7;
2708
+ var store = \u03A4;
2709
+
2692
2710
  // src/pi.ts
2693
2711
  import {
2694
2712
  streamSimple
@@ -2776,7 +2794,8 @@ function makeOpts(opts) {
2776
2794
  reasoning: opts.thinkingLevel,
2777
2795
  thinkingBudgets: opts.thinkingBudgets,
2778
2796
  timeoutMs: opts.timeoutMs,
2779
- maxRetries: opts.maxRetries
2797
+ maxRetries: opts.maxRetries,
2798
+ apiKey: opts.apiKey
2780
2799
  };
2781
2800
  }
2782
2801
  async function run(pieces, args, opts) {
@@ -3147,6 +3166,23 @@ async function runScriptMode(scriptPath) {
3147
3166
  g.\u0392 = \u0392;
3148
3167
  g.\u0391 = \u0391;
3149
3168
  g.\u0393 = \u0393;
3169
+ g.pi = \u03C0;
3170
+ g.Pi = \u03A0;
3171
+ g.ralph = ralph;
3172
+ g.fleet = fleet;
3173
+ g.subagent = subagent;
3174
+ g.debate = debate;
3175
+ g.pipeline = pipeline;
3176
+ g.critique = critique;
3177
+ g.orchestrator = orchestrator;
3178
+ g.thread = thread;
3179
+ g.memory = memory;
3180
+ g.broadcast = broadcast;
3181
+ g.adaptive = adaptive;
3182
+ g.graph = graph;
3183
+ g.team = team;
3184
+ g.learn = learn;
3185
+ g.store = store;
3150
3186
  const { createRequire: createRequire2 } = await import("node:module");
3151
3187
  const __filename = absPath;
3152
3188
  const __dirname = path.dirname(absPath);