toolcraft 0.0.165 → 0.0.167

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/composition.json CHANGED
@@ -113,7 +113,7 @@
113
113
  },
114
114
  {
115
115
  "name": "toolcraft",
116
- "version": "0.0.165",
116
+ "version": "0.0.167",
117
117
  "license": "MIT"
118
118
  },
119
119
  {
@@ -123,7 +123,7 @@
123
123
  },
124
124
  {
125
125
  "name": "toolcraft-schema",
126
- "version": "0.0.165",
126
+ "version": "0.0.167",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -113,7 +113,7 @@
113
113
  },
114
114
  {
115
115
  "name": "toolcraft",
116
- "version": "0.0.165",
116
+ "version": "0.0.167",
117
117
  "license": "MIT"
118
118
  },
119
119
  {
@@ -123,7 +123,7 @@
123
123
  },
124
124
  {
125
125
  "name": "toolcraft-schema",
126
- "version": "0.0.165",
126
+ "version": "0.0.167",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -8,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "name": "toolcraft-schema",
11
- "version": "0.0.165",
11
+ "version": "0.0.167",
12
12
  "license": "MIT"
13
13
  }
14
14
  ]
@@ -1,3 +1,4 @@
1
+ import { graphemes } from "../dashboard/terminal-width.js";
1
2
  import { buildActionContext, resolveAction } from "./actions.js";
2
3
  import { filterRows } from "./filter.js";
3
4
  import { REGION_ALL, REGION_DETAIL, REGION_FOOTER, REGION_HEADER, REGION_LIST, REGION_MODAL, resolveExplorerLayoutMode } from "./state.js";
@@ -47,6 +48,10 @@ export function step(state, event, runtimeHandles = DEFAULT_ACTION_HANDLES) {
47
48
  }
48
49
  function stepKey(state, key, runtimeHandles) {
49
50
  const target = state.bindings.resolve(key);
51
+ if (target?.type === "builtin" && target.id === "quit") {
52
+ const next = state.modal === null ? state : modalDismissed(state, null, runtimeHandles).state;
53
+ return { state: markDirty(next, 0), effects: [{ type: "exit", result: null }] };
54
+ }
50
55
  if (state.modal !== null) {
51
56
  return stepModalKey(state, key, target, runtimeHandles);
52
57
  }
@@ -66,8 +71,6 @@ function stepKey(state, key, runtimeHandles) {
66
71
  }
67
72
  if (target?.type === "builtin") {
68
73
  switch (target.id) {
69
- case "quit":
70
- return { state: markDirty(state, 0), effects: [{ type: "exit", result: null }] };
71
74
  case "filter":
72
75
  return focusFilter(state);
73
76
  case "help":
@@ -126,8 +129,8 @@ function stepKey(state, key, runtimeHandles) {
126
129
  }
127
130
  if (isBackspace(key)) {
128
131
  if (isSecondListFocused(state))
129
- return updateDetailFilter(state, (state.detail.filter ?? "").slice(0, -1));
130
- return updateFilter(state, state.filter.slice(0, -1));
132
+ return updateDetailFilter(state, graphemes(state.detail.filter ?? "").slice(0, -1).join(""));
133
+ return updateFilter(state, graphemes(state.filter).slice(0, -1).join(""));
131
134
  }
132
135
  if (!state.multiSelect && isSelectionSpace(key)) {
133
136
  return mark(state, 0);
@@ -150,7 +153,7 @@ function stepFilterKey(state, key, target, runtimeHandles) {
150
153
  };
151
154
  }
152
155
  if (isBackspace(key)) {
153
- return updateFilter(state, state.filter.slice(0, -1));
156
+ return updateFilter(state, graphemes(state.filter).slice(0, -1).join(""));
154
157
  }
155
158
  if (isPrintable(key)) {
156
159
  return updateFilter(state, `${state.filter}${key.ch}`);
@@ -166,7 +169,7 @@ function stepModalKey(state, key, target, runtimeHandles) {
166
169
  return modalDismissed(state, state.modal.value, runtimeHandles);
167
170
  }
168
171
  if (isBackspace(key)) {
169
- return setModal(state, { ...state.modal, value: state.modal.value.slice(0, -1) });
172
+ return setModal(state, { ...state.modal, value: graphemes(state.modal.value).slice(0, -1).join("") });
170
173
  }
171
174
  if (isPrintable(key)) {
172
175
  return setModal(state, { ...state.modal, value: `${state.modal.value}${key.ch}` });
@@ -726,7 +729,7 @@ function paletteInput(state, key) {
726
729
  return mark(state, 0);
727
730
  }
728
731
  if (isBackspace(key)) {
729
- return setPaletteQuery(state, state.modal.query.slice(0, -1));
732
+ return setPaletteQuery(state, graphemes(state.modal.query).slice(0, -1).join(""));
730
733
  }
731
734
  if (isPrintable(key)) {
732
735
  return setPaletteQuery(state, `${state.modal.query}${key.ch}`);
@@ -73,7 +73,19 @@ export class Prompt extends EventEmitter {
73
73
  return Promise.resolve(CANCEL);
74
74
  }
75
75
  if (this.input.isTTY !== true) {
76
- return this.promptNonTty();
76
+ return this.promptNonTty().then((value) => {
77
+ if (value === CANCEL || !this.trackValue) {
78
+ return value;
79
+ }
80
+ this.setValue(value);
81
+ const error = this.validate?.(this.value);
82
+ if (error) {
83
+ throw error instanceof Error ? error : new Error(error);
84
+ }
85
+ this.state = "submit";
86
+ this.emit("finalize");
87
+ return this.value;
88
+ });
77
89
  }
78
90
  if (this.input.destroyed || this.input.readableEnded) {
79
91
  this.state = "cancel";
@@ -109,27 +121,57 @@ export class Prompt extends EventEmitter {
109
121
  return Promise.reject(new Error(nonTtyPromptMessage()));
110
122
  }
111
123
  readNonTtyLine() {
112
- return new Promise((resolve) => {
113
- const rl = readline.createInterface({ input: this.input, terminal: false });
124
+ if (this.input.readableEnded) {
125
+ return Promise.resolve("");
126
+ }
127
+ if (this.input.destroyed) {
128
+ this.state = "cancel";
129
+ return Promise.resolve(CANCEL);
130
+ }
131
+ return new Promise((resolve, reject) => {
132
+ let rl = null;
114
133
  let settled = false;
115
134
  const settle = (value) => {
116
135
  if (settled) {
117
136
  return;
118
137
  }
119
138
  settled = true;
120
- this.signal?.removeEventListener("abort", onAbort);
121
- rl.close();
122
- resolve(value);
139
+ this.input.removeListener("close", onCancel);
140
+ this.signal?.removeEventListener("abort", onCancel);
141
+ rl?.removeListener("error", settle);
142
+ rl?.removeListener("line", settle);
143
+ rl?.removeListener("close", onClose);
144
+ rl?.close();
145
+ if (value instanceof Error) {
146
+ reject(value);
147
+ }
148
+ else {
149
+ resolve(value);
150
+ }
123
151
  };
124
- const onAbort = () => {
152
+ const onCancel = () => {
125
153
  this.state = "cancel";
126
154
  settle(CANCEL);
127
155
  };
156
+ const onClose = () => settle(rl?.line ?? "");
157
+ this.input.once("close", onCancel);
158
+ rl = readline.createInterface({ input: this.input, terminal: false });
159
+ if (settled) {
160
+ rl.close();
161
+ return;
162
+ }
163
+ rl.once("error", settle);
128
164
  rl.once("line", settle);
129
- rl.once("close", () => settle(rl.line));
130
- this.signal?.addEventListener("abort", onAbort, { once: true });
165
+ rl.once("close", onClose);
166
+ this.signal?.addEventListener("abort", onCancel, { once: true });
131
167
  if (this.signal?.aborted) {
132
- onAbort();
168
+ onCancel();
169
+ }
170
+ else if (this.input.readableEnded) {
171
+ settle(rl.line);
172
+ }
173
+ else if (this.input.destroyed) {
174
+ onCancel();
133
175
  }
134
176
  });
135
177
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft-schema",
3
- "version": "0.0.165",
3
+ "version": "0.0.167",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft",
3
- "version": "0.0.165",
3
+ "version": "0.0.167",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -158,7 +158,7 @@
158
158
  "yaml"
159
159
  ],
160
160
  "optionalDependencies": {
161
- "toolcraft-schema": "0.0.165",
161
+ "toolcraft-schema": "0.0.167",
162
162
  "toolcraft-design": "*",
163
163
  "@poe-code/frontmatter": "*",
164
164
  "@poe-code/agent-mcp-config": "*",