@vitos-pizza/vitos-pizza 0.3.1 → 0.4.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.
Files changed (37) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +42 -11
  3. package/README.md +31 -4
  4. package/assets/architecture.png +0 -0
  5. package/assets/architecture.svg +97 -0
  6. package/package.json +22 -12
  7. package/packages/agent-mode/package.json +3 -3
  8. package/packages/agent-mode/src/plan-instructions.ts +19 -7
  9. package/packages/hypa/extensions/index.ts +16 -0
  10. package/packages/hypa/package.json +23 -0
  11. package/packages/hypa/scripts/smoke.mjs +50 -0
  12. package/packages/hypa/src/config.ts +37 -0
  13. package/packages/hypa/src/seed.ts +22 -0
  14. package/packages/hypa/tsconfig.json +13 -0
  15. package/packages/keybindings/package.json +1 -1
  16. package/packages/permission-system/package.json +2 -2
  17. package/packages/permission-system/presets/default.json +8 -0
  18. package/packages/permission-system/presets/plan.json +6 -0
  19. package/packages/permission-system/presets/yolo.json +1 -0
  20. package/packages/question/extensions/index.ts +54 -21
  21. package/packages/question/package.json +1 -1
  22. package/packages/question/src/forwarding/file-watcher.ts +41 -11
  23. package/packages/question/src/forwarding/forwarder.ts +61 -27
  24. package/packages/question/src/question-ui.ts +773 -78
  25. package/packages/question/src/register-tool.ts +351 -40
  26. package/packages/question/src/types.ts +79 -7
  27. package/packages/session-title/package.json +3 -3
  28. package/packages/settings-preset/package.json +1 -1
  29. package/packages/subagents/agents/planner.md +3 -2
  30. package/packages/subagents/agents/scout.md +2 -1
  31. package/packages/subagents/agents/worker.md +3 -2
  32. package/packages/subagents/package.json +1 -1
  33. package/packages/todoist/package.json +1 -1
  34. package/packages/ui-enhancements/package.json +1 -1
  35. package/packages/ui-enhancements/src/chrome/resize-recovery.ts +71 -14
  36. package/packages/websearch/package.json +1 -1
  37. package/scripts/sync-pi-manifest.mjs +18 -12
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: worker
3
3
  description: Implementation agent for approved plans and focused tasks
4
- tools: read, grep, find, ls, bash, edit, write
4
+ tools: hypa_read, hypa_grep, hypa_find, hypa_ls, bash, edit, write
5
5
  thinking: high
6
6
  systemPromptMode: replace
7
7
  ---
@@ -10,9 +10,10 @@ You are worker: the single writer thread. Execute the assigned task or approved
10
10
 
11
11
  Rules:
12
12
  - Read inherited context/plan first; validate against the actual code.
13
+ - Use `hypa_read` / `hypa_grep` / `hypa_find` / `hypa_ls` for codebase exploration.
13
14
  - Prefer the smallest correct change; follow existing patterns.
14
15
  - No speculative scaffolding, placeholders, TODOs, or silent scope changes.
15
- - Use `bash` for inspection, validation, and relevant tests.
16
+ - Use `bash` for inspection, validation, and relevant tests (Hypa may rewrite bash for compressed output — keep using `bash`, not `hypa_shell`).
16
17
  - If the task expects file edits and you made none, do not claim success.
17
18
 
18
19
  Final response shape:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/subagents",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Subagent delegation for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/todoist",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "In-memory task management with TUI widget and optional Todoist MCP sync for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/ui-enhancements",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "TUI and UI enhancements for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,12 @@
1
1
  /** Debounce window after the last resize event before forcing a full redraw. */
2
2
  export const RESIZE_RECOVERY_DEBOUNCE_MS = 150;
3
3
 
4
+ /** Interval between recovery retries when size/target is not yet ready. */
5
+ export const RESIZE_RECOVERY_RETRY_MS = 50;
6
+
7
+ /** Max time to keep retrying after debounce settles. */
8
+ export const RESIZE_RECOVERY_RETRY_WINDOW_MS = 1000;
9
+
4
10
  export type ResizeRecoveryTarget = {
5
11
  invalidate(): void;
6
12
  requestRender(force?: boolean): void;
@@ -8,6 +14,8 @@ export type ResizeRecoveryTarget = {
8
14
 
9
15
  export type ResizeRecoveryOptions = {
10
16
  debounceMs?: number;
17
+ retryMs?: number;
18
+ retryWindowMs?: number;
11
19
  getColumns?: () => number | undefined;
12
20
  getRows?: () => number | undefined;
13
21
  getTarget?: () => ResizeRecoveryTarget | undefined;
@@ -17,12 +25,17 @@ export type ResizeRecoveryOptions = {
17
25
 
18
26
  /**
19
27
  * After terminal resize settles, force a full TUI invalidate+redraw.
20
- * Skips frames where columns/rows are falsy (Windows can briefly report 0).
28
+ * When columns/rows are briefly falsy (Windows) or the TUI target is not
29
+ * ready yet, retries until dimensions/target are available or the retry
30
+ * window elapses.
21
31
  */
22
32
  export function attachResizeRecovery(
23
33
  options: ResizeRecoveryOptions = {},
24
34
  ): () => void {
25
35
  const debounceMs = options.debounceMs ?? RESIZE_RECOVERY_DEBOUNCE_MS;
36
+ const retryMs = options.retryMs ?? RESIZE_RECOVERY_RETRY_MS;
37
+ const retryWindowMs =
38
+ options.retryWindowMs ?? RESIZE_RECOVERY_RETRY_WINDOW_MS;
26
39
  const getColumns = options.getColumns ?? (() => process.stdout.columns);
27
40
  const getRows = options.getRows ?? (() => process.stdout.rows);
28
41
  const getTarget = options.getTarget ?? (() => undefined);
@@ -37,27 +50,71 @@ export function attachResizeRecovery(
37
50
  process.stdout.off(event, listener);
38
51
  });
39
52
 
40
- let timer: ReturnType<typeof setTimeout> | undefined;
53
+ let debounceTimer: ReturnType<typeof setTimeout> | undefined;
54
+ let retryTimer: ReturnType<typeof setTimeout> | undefined;
55
+ let retryDeadline = 0;
56
+
57
+ const clearDebounce = () => {
58
+ if (debounceTimer) clearTimeout(debounceTimer);
59
+ debounceTimer = undefined;
60
+ };
61
+
62
+ const clearRetry = () => {
63
+ if (retryTimer) clearTimeout(retryTimer);
64
+ retryTimer = undefined;
65
+ retryDeadline = 0;
66
+ };
67
+
68
+ const tryRecover = (): boolean => {
69
+ const cols = getColumns();
70
+ const rows = getRows();
71
+ if (!cols || !rows) return false;
72
+ const target = getTarget();
73
+ if (!target) return false;
74
+ target.invalidate();
75
+ target.requestRender(true);
76
+ return true;
77
+ };
78
+
79
+ const scheduleRetry = () => {
80
+ if (retryTimer) return;
81
+ retryTimer = setTimeout(() => {
82
+ retryTimer = undefined;
83
+ if (tryRecover()) {
84
+ clearRetry();
85
+ return;
86
+ }
87
+ if (Date.now() >= retryDeadline) {
88
+ retryDeadline = 0;
89
+ return;
90
+ }
91
+ scheduleRetry();
92
+ }, retryMs);
93
+ };
94
+
95
+ const startRecovery = () => {
96
+ if (tryRecover()) {
97
+ clearRetry();
98
+ return;
99
+ }
100
+ retryDeadline = Date.now() + retryWindowMs;
101
+ scheduleRetry();
102
+ };
41
103
 
42
104
  const onResize = () => {
43
- if (timer) clearTimeout(timer);
44
- timer = setTimeout(() => {
45
- timer = undefined;
46
- const cols = getColumns();
47
- const rows = getRows();
48
- if (!cols || !rows) return;
49
- const target = getTarget();
50
- if (!target) return;
51
- target.invalidate();
52
- target.requestRender(true);
105
+ clearDebounce();
106
+ clearRetry();
107
+ debounceTimer = setTimeout(() => {
108
+ debounceTimer = undefined;
109
+ startRecovery();
53
110
  }, debounceMs);
54
111
  };
55
112
 
56
113
  on("resize", onResize);
57
114
 
58
115
  return () => {
59
- if (timer) clearTimeout(timer);
60
- timer = undefined;
116
+ clearDebounce();
117
+ clearRetry();
61
118
  off("resize", onResize);
62
119
  };
63
120
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitos-pizza/websearch",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Web search and URL reading for Vito's Pizzeria Pi distribution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -8,9 +8,20 @@ const rootPkgPath = join(root, "package.json");
8
8
 
9
9
  const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
10
10
 
11
- const BUNDLED_FIRST = [];
12
- const BUNDLED_LAST = [];
13
- const LOCAL_ORDER = ["permission-system", "settings-preset", "question", "ui-enhancements", "agent-mode", "subagents", "websearch", "session-title", "todoist", "keybindings"];
11
+ /** Local modules after permission-system, before agent-mode (plan setActiveTools). */
12
+ const LOCAL_ORDER = [
13
+ "permission-system",
14
+ "settings-preset",
15
+ "hypa",
16
+ "question",
17
+ "ui-enhancements",
18
+ "subagents",
19
+ "websearch",
20
+ "session-title",
21
+ "keybindings",
22
+ "agent-mode",
23
+ "todoist",
24
+ ];
14
25
 
15
26
  function loadJson(path) {
16
27
  return JSON.parse(readFileSync(path, "utf8"));
@@ -157,9 +168,9 @@ function sortPackagesByRequires(packages) {
157
168
 
158
169
  const packages = discoverPackages();
159
170
  const sortedPackages = sortPackagesByRequires(packages);
160
- const packageByDir = new Map(packages.map((p) => [p.dir, p]));
161
171
  const rootPkg = loadJson(rootPkgPath);
162
172
  const existingDeps = rootPkg.dependencies ?? {};
173
+ const piBundled = Array.isArray(rootPkg.piBundled) ? rootPkg.piBundled : [];
163
174
 
164
175
  const dependencies = {};
165
176
  for (const [name, spec] of Object.entries(existingDeps)) {
@@ -174,7 +185,7 @@ for (const { dir, pkg } of packages) {
174
185
 
175
186
  const piEntries = [];
176
187
 
177
- for (const npmName of BUNDLED_FIRST) {
188
+ for (const npmName of piBundled) {
178
189
  const pi = resolveBundledPaths(npmName);
179
190
  if (pi) piEntries.push({ pi });
180
191
  }
@@ -185,17 +196,12 @@ for (const entry of sortedPackages) {
185
196
  });
186
197
  }
187
198
 
188
- for (const npmName of BUNDLED_LAST) {
189
- const pi = resolveBundledPaths(npmName);
190
- if (pi) piEntries.push({ pi });
191
- }
192
-
193
199
  rootPkg.dependencies = dependencies;
200
+ rootPkg.piBundled = piBundled;
194
201
  rootPkg.pi = mergePiManifest(piEntries);
195
202
 
196
203
  writeFileSync(rootPkgPath, `${JSON.stringify(rootPkg, null, "\t")}\n`, "utf8");
197
204
 
198
- const bundled = [...BUNDLED_FIRST, ...BUNDLED_LAST].join(", ");
199
205
  console.log(
200
- `Synced vitos-pizza manifest: ${packages.length} local module(s) [${sortedPackages.map((p) => p.dir).join(", ")}], bundled: ${bundled || "(none)"}`,
206
+ `Synced vitos-pizza manifest: ${packages.length} local module(s) [${sortedPackages.map((p) => p.dir).join(", ")}], piBundled: ${piBundled.join(", ") || "(none)"}`,
201
207
  );