@hncode/hncode 0.3.5 → 0.4.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.
Files changed (147) hide show
  1. package/package.json +4 -2
  2. package/src/agent-task.js +154 -84
  3. package/src/agent.js +533 -145
  4. package/src/clipboard.js +5 -2
  5. package/src/colors.js +242 -238
  6. package/src/config.js +217 -17
  7. package/src/file-history.js +177 -0
  8. package/src/hooks.js +11 -1
  9. package/src/i18n.js +389 -0
  10. package/src/index.js +46 -3
  11. package/src/llm.js +139 -16
  12. package/src/permissions.js +120 -0
  13. package/src/session-hub.js +407 -0
  14. package/src/session.js +31 -0
  15. package/src/term.js +19 -3
  16. package/src/tool-result.js +236 -0
  17. package/src/tools/agent.js +11 -0
  18. package/src/tools/bash.js +84 -17
  19. package/src/tools/edit.js +192 -32
  20. package/src/tools/file-lines.js +5 -0
  21. package/src/tools/index.js +4 -0
  22. package/src/tools/memory.js +88 -0
  23. package/src/tools/read-media-file.js +85 -68
  24. package/src/tools/read.js +15 -1
  25. package/src/tools/utils.js +14 -0
  26. package/src/tools/write.js +35 -5
  27. package/src/tui.js +11665 -9179
  28. package/src/web-auth.js +98 -0
  29. package/src/web-daemon-cli.js +63 -0
  30. package/src/web-daemon-client.js +203 -0
  31. package/src/web-daemon.js +871 -0
  32. package/src/web-public/app.css +1509 -0
  33. package/src/web-public/app.js +2913 -0
  34. package/src/web-public/complete.js +154 -0
  35. package/src/web-public/fonts/JetBrainsMono-Bold.woff2 +0 -0
  36. package/src/web-public/fonts/JetBrainsMono-Regular.woff2 +0 -0
  37. package/src/web-public/fonts/noto-sans-sc-100-400-normal.woff2 +0 -0
  38. package/src/web-public/fonts/noto-sans-sc-101-400-normal.woff2 +0 -0
  39. package/src/web-public/fonts/noto-sans-sc-102-400-normal.woff2 +0 -0
  40. package/src/web-public/fonts/noto-sans-sc-103-400-normal.woff2 +0 -0
  41. package/src/web-public/fonts/noto-sans-sc-104-400-normal.woff2 +0 -0
  42. package/src/web-public/fonts/noto-sans-sc-105-400-normal.woff2 +0 -0
  43. package/src/web-public/fonts/noto-sans-sc-106-400-normal.woff2 +0 -0
  44. package/src/web-public/fonts/noto-sans-sc-107-400-normal.woff2 +0 -0
  45. package/src/web-public/fonts/noto-sans-sc-108-400-normal.woff2 +0 -0
  46. package/src/web-public/fonts/noto-sans-sc-109-400-normal.woff2 +0 -0
  47. package/src/web-public/fonts/noto-sans-sc-110-400-normal.woff2 +0 -0
  48. package/src/web-public/fonts/noto-sans-sc-111-400-normal.woff2 +0 -0
  49. package/src/web-public/fonts/noto-sans-sc-112-400-normal.woff2 +0 -0
  50. package/src/web-public/fonts/noto-sans-sc-113-400-normal.woff2 +0 -0
  51. package/src/web-public/fonts/noto-sans-sc-114-400-normal.woff2 +0 -0
  52. package/src/web-public/fonts/noto-sans-sc-115-400-normal.woff2 +0 -0
  53. package/src/web-public/fonts/noto-sans-sc-116-400-normal.woff2 +0 -0
  54. package/src/web-public/fonts/noto-sans-sc-117-400-normal.woff2 +0 -0
  55. package/src/web-public/fonts/noto-sans-sc-118-400-normal.woff2 +0 -0
  56. package/src/web-public/fonts/noto-sans-sc-119-400-normal.woff2 +0 -0
  57. package/src/web-public/fonts/noto-sans-sc-21-400-normal.woff2 +0 -0
  58. package/src/web-public/fonts/noto-sans-sc-22-400-normal.woff2 +0 -0
  59. package/src/web-public/fonts/noto-sans-sc-23-400-normal.woff2 +0 -0
  60. package/src/web-public/fonts/noto-sans-sc-24-400-normal.woff2 +0 -0
  61. package/src/web-public/fonts/noto-sans-sc-25-400-normal.woff2 +0 -0
  62. package/src/web-public/fonts/noto-sans-sc-26-400-normal.woff2 +0 -0
  63. package/src/web-public/fonts/noto-sans-sc-27-400-normal.woff2 +0 -0
  64. package/src/web-public/fonts/noto-sans-sc-28-400-normal.woff2 +0 -0
  65. package/src/web-public/fonts/noto-sans-sc-29-400-normal.woff2 +0 -0
  66. package/src/web-public/fonts/noto-sans-sc-30-400-normal.woff2 +0 -0
  67. package/src/web-public/fonts/noto-sans-sc-31-400-normal.woff2 +0 -0
  68. package/src/web-public/fonts/noto-sans-sc-32-400-normal.woff2 +0 -0
  69. package/src/web-public/fonts/noto-sans-sc-33-400-normal.woff2 +0 -0
  70. package/src/web-public/fonts/noto-sans-sc-34-400-normal.woff2 +0 -0
  71. package/src/web-public/fonts/noto-sans-sc-35-400-normal.woff2 +0 -0
  72. package/src/web-public/fonts/noto-sans-sc-36-400-normal.woff2 +0 -0
  73. package/src/web-public/fonts/noto-sans-sc-37-400-normal.woff2 +0 -0
  74. package/src/web-public/fonts/noto-sans-sc-38-400-normal.woff2 +0 -0
  75. package/src/web-public/fonts/noto-sans-sc-39-400-normal.woff2 +0 -0
  76. package/src/web-public/fonts/noto-sans-sc-4-400-normal.woff2 +0 -0
  77. package/src/web-public/fonts/noto-sans-sc-40-400-normal.woff2 +0 -0
  78. package/src/web-public/fonts/noto-sans-sc-41-400-normal.woff2 +0 -0
  79. package/src/web-public/fonts/noto-sans-sc-42-400-normal.woff2 +0 -0
  80. package/src/web-public/fonts/noto-sans-sc-43-400-normal.woff2 +0 -0
  81. package/src/web-public/fonts/noto-sans-sc-44-400-normal.woff2 +0 -0
  82. package/src/web-public/fonts/noto-sans-sc-45-400-normal.woff2 +0 -0
  83. package/src/web-public/fonts/noto-sans-sc-46-400-normal.woff2 +0 -0
  84. package/src/web-public/fonts/noto-sans-sc-47-400-normal.woff2 +0 -0
  85. package/src/web-public/fonts/noto-sans-sc-48-400-normal.woff2 +0 -0
  86. package/src/web-public/fonts/noto-sans-sc-49-400-normal.woff2 +0 -0
  87. package/src/web-public/fonts/noto-sans-sc-5-400-normal.woff2 +0 -0
  88. package/src/web-public/fonts/noto-sans-sc-50-400-normal.woff2 +0 -0
  89. package/src/web-public/fonts/noto-sans-sc-51-400-normal.woff2 +0 -0
  90. package/src/web-public/fonts/noto-sans-sc-52-400-normal.woff2 +0 -0
  91. package/src/web-public/fonts/noto-sans-sc-53-400-normal.woff2 +0 -0
  92. package/src/web-public/fonts/noto-sans-sc-54-400-normal.woff2 +0 -0
  93. package/src/web-public/fonts/noto-sans-sc-55-400-normal.woff2 +0 -0
  94. package/src/web-public/fonts/noto-sans-sc-56-400-normal.woff2 +0 -0
  95. package/src/web-public/fonts/noto-sans-sc-57-400-normal.woff2 +0 -0
  96. package/src/web-public/fonts/noto-sans-sc-58-400-normal.woff2 +0 -0
  97. package/src/web-public/fonts/noto-sans-sc-59-400-normal.woff2 +0 -0
  98. package/src/web-public/fonts/noto-sans-sc-6-400-normal.woff2 +0 -0
  99. package/src/web-public/fonts/noto-sans-sc-60-400-normal.woff2 +0 -0
  100. package/src/web-public/fonts/noto-sans-sc-61-400-normal.woff2 +0 -0
  101. package/src/web-public/fonts/noto-sans-sc-62-400-normal.woff2 +0 -0
  102. package/src/web-public/fonts/noto-sans-sc-63-400-normal.woff2 +0 -0
  103. package/src/web-public/fonts/noto-sans-sc-64-400-normal.woff2 +0 -0
  104. package/src/web-public/fonts/noto-sans-sc-65-400-normal.woff2 +0 -0
  105. package/src/web-public/fonts/noto-sans-sc-66-400-normal.woff2 +0 -0
  106. package/src/web-public/fonts/noto-sans-sc-67-400-normal.woff2 +0 -0
  107. package/src/web-public/fonts/noto-sans-sc-68-400-normal.woff2 +0 -0
  108. package/src/web-public/fonts/noto-sans-sc-69-400-normal.woff2 +0 -0
  109. package/src/web-public/fonts/noto-sans-sc-70-400-normal.woff2 +0 -0
  110. package/src/web-public/fonts/noto-sans-sc-71-400-normal.woff2 +0 -0
  111. package/src/web-public/fonts/noto-sans-sc-72-400-normal.woff2 +0 -0
  112. package/src/web-public/fonts/noto-sans-sc-73-400-normal.woff2 +0 -0
  113. package/src/web-public/fonts/noto-sans-sc-74-400-normal.woff2 +0 -0
  114. package/src/web-public/fonts/noto-sans-sc-75-400-normal.woff2 +0 -0
  115. package/src/web-public/fonts/noto-sans-sc-76-400-normal.woff2 +0 -0
  116. package/src/web-public/fonts/noto-sans-sc-77-400-normal.woff2 +0 -0
  117. package/src/web-public/fonts/noto-sans-sc-78-400-normal.woff2 +0 -0
  118. package/src/web-public/fonts/noto-sans-sc-79-400-normal.woff2 +0 -0
  119. package/src/web-public/fonts/noto-sans-sc-80-400-normal.woff2 +0 -0
  120. package/src/web-public/fonts/noto-sans-sc-81-400-normal.woff2 +0 -0
  121. package/src/web-public/fonts/noto-sans-sc-82-400-normal.woff2 +0 -0
  122. package/src/web-public/fonts/noto-sans-sc-83-400-normal.woff2 +0 -0
  123. package/src/web-public/fonts/noto-sans-sc-84-400-normal.woff2 +0 -0
  124. package/src/web-public/fonts/noto-sans-sc-85-400-normal.woff2 +0 -0
  125. package/src/web-public/fonts/noto-sans-sc-86-400-normal.woff2 +0 -0
  126. package/src/web-public/fonts/noto-sans-sc-87-400-normal.woff2 +0 -0
  127. package/src/web-public/fonts/noto-sans-sc-88-400-normal.woff2 +0 -0
  128. package/src/web-public/fonts/noto-sans-sc-89-400-normal.woff2 +0 -0
  129. package/src/web-public/fonts/noto-sans-sc-90-400-normal.woff2 +0 -0
  130. package/src/web-public/fonts/noto-sans-sc-91-400-normal.woff2 +0 -0
  131. package/src/web-public/fonts/noto-sans-sc-97-400-normal.woff2 +0 -0
  132. package/src/web-public/fonts/noto-sans-sc-98-400-normal.woff2 +0 -0
  133. package/src/web-public/fonts/noto-sans-sc-99-400-normal.woff2 +0 -0
  134. package/src/web-public/fonts/noto-sans-sc.css +775 -0
  135. package/src/web-public/fonts.css +31 -0
  136. package/src/web-public/home.css +222 -0
  137. package/src/web-public/home.html +33 -0
  138. package/src/web-public/home.js +160 -0
  139. package/src/web-public/i18n.js +983 -0
  140. package/src/web-public/index.html +196 -0
  141. package/src/web-public/login.css +123 -0
  142. package/src/web-public/login.html +25 -0
  143. package/src/web-public/login.js +46 -0
  144. package/src/web-public/settings.js +290 -0
  145. package/src/web-ws.js +226 -0
  146. package/src/web.js +380 -0
  147. package/src/tui.js.bak_20260921_191527 +0 -9203
@@ -0,0 +1,154 @@
1
+
2
+
3
+
4
+ const MAX_ITEMS = 50;
5
+
6
+ export class Completer {
7
+
8
+ constructor(input, box, opts) {
9
+ this.input = input;
10
+ this.box = box;
11
+ this.getCommands = opts.getCommands || (() => []);
12
+ this.getFiles = opts.getFiles || (() => []);
13
+ this.onAccept = opts.onAccept || (() => {});
14
+ this.onSubmit = opts.onSubmit || (() => {});
15
+ this.items = [];
16
+ this.sel = 0;
17
+ this.mode = null;
18
+ this.query = '';
19
+ this.range = { start: 0, end: 0 };
20
+ }
21
+
22
+ get open() { return this.mode !== null; }
23
+
24
+ refresh() {
25
+ const value = this.input.value;
26
+ const caret = this.input.selectionStart == null ? value.length : this.input.selectionStart;
27
+ const hit = detect(value, caret);
28
+
29
+ if (!hit) { this.close(); return; }
30
+ this.mode = hit.mode;
31
+ this.query = hit.query;
32
+ this.range = { start: hit.start, end: caret };
33
+
34
+ const all = hit.mode === 'command' ? this.getCommands() : this.getFiles();
35
+ this.items = filterItems(all, hit, MAX_ITEMS);
36
+ if (!this.items.length) { this.close(); return; }
37
+
38
+ this.sel = Math.min(this.sel, this.items.length - 1);
39
+ this.render();
40
+ }
41
+
42
+ close() {
43
+ this.mode = null;
44
+ this.items = [];
45
+ this.sel = 0;
46
+ this.box.hidden = true;
47
+ this.box.textContent = '';
48
+ }
49
+
50
+ move(delta) {
51
+ if (!this.open || !this.items.length) return false;
52
+ this.sel = (this.sel + delta + this.items.length) % this.items.length;
53
+ this.render();
54
+ return true;
55
+ }
56
+
57
+ accept() {
58
+ if (!this.open || !this.items.length) return false;
59
+ const it = this.items[this.sel];
60
+ const insert = this.mode === 'command' ? '/' + it.name : '@' + it.rel;
61
+
62
+ const suffix = this.mode === 'command' ? ' ' : '';
63
+ const value = this.input.value;
64
+ const next = value.slice(0, this.range.start) + insert + suffix + value.slice(this.range.end);
65
+ const caret = this.range.start + insert.length + suffix.length;
66
+ this.close();
67
+ this.onAccept(next, caret);
68
+ return true;
69
+ }
70
+
71
+ run() {
72
+ if (!this.open || !this.items.length) return false;
73
+ const it = this.items[this.sel];
74
+ if (this.mode === 'command') {
75
+ this.close();
76
+ this.onSubmit('/' + it.name);
77
+ return true;
78
+ }
79
+ return this.accept();
80
+ }
81
+
82
+ render() {
83
+ const box = this.box;
84
+ box.textContent = '';
85
+ for (let i = 0; i < this.items.length; i++) {
86
+ const it = this.items[i];
87
+ const row = document.createElement('div');
88
+ row.className = 'comp-item' + (i === this.sel ? ' is-sel' : '');
89
+ const name = document.createElement('span');
90
+ name.className = 'comp-name';
91
+ name.textContent = this.mode === 'command' ? '/' + it.name : it.rel;
92
+ row.appendChild(name);
93
+ const meta = this.mode === 'command'
94
+ ? [it.argumentHint, it.desc].filter(Boolean).join(' ')
95
+ : (it.isDir ? 'directory' : '');
96
+ if (meta) {
97
+ const sub = document.createElement('span');
98
+ sub.className = 'comp-sub';
99
+ sub.textContent = meta;
100
+ row.appendChild(sub);
101
+ }
102
+ row.addEventListener('mousedown', (ev) => {
103
+ ev.preventDefault();
104
+ this.sel = i;
105
+ this.run();
106
+ });
107
+ box.appendChild(row);
108
+ }
109
+ box.hidden = false;
110
+ const sel = box.children[this.sel];
111
+ if (sel && sel.scrollIntoView) sel.scrollIntoView({ block: 'nearest' });
112
+ }
113
+ }
114
+
115
+ export function detect(value, caret) {
116
+ const v = String(value == null ? '' : value);
117
+ const c = Math.max(0, Math.min(v.length, caret == null ? v.length : caret));
118
+ let start = c;
119
+ while (start > 0 && !/\s/.test(v[start - 1])) start--;
120
+ const token = v.slice(start, c);
121
+ if (!token) return null;
122
+ if (token[0] === '/') return { mode: 'command', query: token.slice(1), start, token };
123
+ if (token[0] === '@') return { mode: 'file', query: token.slice(1), start, token };
124
+ return null;
125
+ }
126
+
127
+ export function filterItems(all, hit, limit = MAX_ITEMS) {
128
+ const q = String(hit.query || '').toLowerCase();
129
+ const out = [];
130
+ if (hit.mode === 'command') {
131
+ for (const it of all || []) {
132
+ if (!it || !it.name) continue;
133
+ const name = String(it.name).toLowerCase();
134
+
135
+ const aliasHit = (it.aliases || []).some((a) => String(a).toLowerCase().startsWith(q));
136
+ if (q && !name.startsWith(q) && !aliasHit) continue;
137
+
138
+ out.push({ rank: q && name.startsWith(q) ? 0 : 1, it });
139
+ }
140
+ } else {
141
+ for (const it of all || []) {
142
+ if (!it || !it.rel) continue;
143
+ const rel = String(it.rel).toLowerCase();
144
+ const base = rel.slice(rel.lastIndexOf('/') + 1);
145
+ if (q && !rel.includes(q)) continue;
146
+
147
+ const rank = (q && base.startsWith(q) ? 0 : 1) + (it.isDir ? 0 : 0.5);
148
+ out.push({ rank, it });
149
+ }
150
+ }
151
+ out.sort((a, b) => a.rank - b.rank
152
+ || String(a.it.name || a.it.rel).length - String(b.it.name || b.it.rel).length);
153
+ return out.slice(0, limit).map((x) => x.it);
154
+ }