@mjasnikovs/pi-task 0.17.2 → 0.17.3

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.
@@ -7,8 +7,8 @@ const DEFAULTS = {
7
7
  compressReasoning: true,
8
8
  autoCommit: true,
9
9
  orientation: true,
10
- enforceGuidelines: false,
11
- verifyWork: false
10
+ enforceGuidelines: true,
11
+ verifyWork: true
12
12
  };
13
13
  const CONFIG_PATH = path.join(os.homedir(), '.config', 'pi-task', 'config.json');
14
14
  const _g = globalThis;
@@ -1,6 +1,51 @@
1
- import { SettingsList } from '@earendil-works/pi-tui';
1
+ import { SettingsList, visibleWidth } from '@earendil-works/pi-tui';
2
2
  import { registerBridgeCommand } from '../remote/bridge.js';
3
3
  import { getConfig, saveConfig } from './config.js';
4
+ const CONFIG_TITLE = 'pi-task settings';
5
+ /**
6
+ * Frames a child component (the settings list) in a rounded border with a title
7
+ * woven into the top edge. Without this the overlay's content sits flush against
8
+ * the chat scrollback and reads as just more console text; the border gives it a
9
+ * distinct panel. Layout mirrors {@link renderQuestionBox}'s box chrome: render
10
+ * the child at the inner width, pad each line so the right edge lines up, then
11
+ * frame. Input and invalidation are forwarded straight through to the child.
12
+ */
13
+ class BorderedBox {
14
+ child;
15
+ title;
16
+ border;
17
+ titleColor;
18
+ constructor(child, title, border, titleColor) {
19
+ this.child = child;
20
+ this.title = title;
21
+ this.border = border;
22
+ this.titleColor = titleColor;
23
+ }
24
+ render(width) {
25
+ const innerWidth = Math.max(1, width - 4); // "│ " + content + " │"
26
+ const dash = (n) => '─'.repeat(Math.max(0, n));
27
+ // Top border with the title woven in: "╭─ pi-task settings ─…─╮".
28
+ const tag = ` ${this.title} `;
29
+ const lead = 1; // one dash before the title
30
+ const rest = width - 2 - lead - visibleWidth(tag);
31
+ const top = rest >= 0 ?
32
+ this.border(`╭${dash(lead)}`) + this.titleColor(tag) + this.border(`${dash(rest)}╮`)
33
+ : this.border(`╭${dash(width - 2)}╮`);
34
+ const body = this.child.render(innerWidth).map(line => {
35
+ const pad = innerWidth - visibleWidth(line);
36
+ const padded = pad > 0 ? line + ' '.repeat(pad) : line;
37
+ return this.border('│ ') + padded + this.border(' │');
38
+ });
39
+ const bottom = this.border(`╰${dash(width - 2)}╯`);
40
+ return [top, ...body, bottom];
41
+ }
42
+ invalidate() {
43
+ this.child.invalidate();
44
+ }
45
+ handleInput(data) {
46
+ this.child.handleInput(data);
47
+ }
48
+ }
4
49
  const ITEMS = [
5
50
  { id: 'remote', label: 'remote', description: 'Remote UI server (QR code, phone access)' },
6
51
  {
@@ -58,8 +103,8 @@ async function handleTaskConfig(_args, ctx) {
58
103
  cfg[id] = newValue === 'on';
59
104
  saveConfig(cfg).catch(() => { });
60
105
  }, () => done(undefined));
61
- return list;
62
- }, { overlay: true, overlayOptions: { width: 54 } });
106
+ return new BorderedBox(list, CONFIG_TITLE, s => theme.fg('borderMuted', s), s => theme.fg('accent', theme.bold(s)));
107
+ }, { overlay: true, overlayOptions: { width: 58 } });
63
108
  }
64
109
  export function registerConfig(pi) {
65
110
  registerBridgeCommand(pi, 'task-config', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mjasnikovs/pi-task",
3
- "version": "0.17.2",
3
+ "version": "0.17.3",
4
4
  "description": "Deterministic spec-orchestration for local models, with a bundled real-time remote web view and web/docs/fetch/worker subagent tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",