@dmsdc-ai/aterm 0.1.12 → 0.1.14

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/bin/aterm.js CHANGED
@@ -5,7 +5,6 @@ import { spawn } from 'node:child_process';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import {
7
7
  ensureUserLayout,
8
- getUserAtermConfigPath,
9
8
  resolveAigentryConfig,
10
9
  } from '../lib/aigentry.js';
11
10
 
@@ -19,69 +18,12 @@ const packageJson = JSON.parse(
19
18
  fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'),
20
19
  );
21
20
 
22
- function printVersionAndExit() {
21
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
23
22
  console.log(packageJson.version);
24
23
  process.exit(0);
25
24
  }
26
25
 
27
- function readUserSetupState() {
28
- const configPath = getUserAtermConfigPath();
29
- if (!fs.existsSync(configPath)) {
30
- return {
31
- configPath,
32
- setupCompleted: false,
33
- };
34
- }
35
-
36
- try {
37
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
38
- return {
39
- configPath,
40
- setupCompleted: config.setupCompleted === true,
41
- };
42
- } catch (error) {
43
- console.warn(`[aterm] invalid user config, rerunning setup: ${error.message}`);
44
- return {
45
- configPath,
46
- setupCompleted: false,
47
- };
48
- }
49
- }
50
-
51
- async function maybeRunFirstRunWizard() {
52
- ensureUserLayout({ version: packageJson.version });
53
- const setupState = readUserSetupState();
54
- if (setupState.setupCompleted) {
55
- return;
56
- }
57
-
58
- let wizardModule;
59
- try {
60
- wizardModule = await import('../scripts/tui-installer.js');
61
- } catch (error) {
62
- console.warn(`[aterm] setup wizard unavailable, launching with defaults (${error.message})`);
63
- return;
64
- }
65
-
66
- if (!wizardModule.shouldRunFirstRunWizard()) {
67
- return;
68
- }
69
-
70
- const context = wizardModule.buildFirstRunWizardContext(packageJson.version, process.cwd());
71
- const wizardResult = await wizardModule.runFirstRunWizard(context);
72
- if (!wizardResult) {
73
- process.exit(0);
74
- }
75
-
76
- await wizardModule.completeFirstRunWizard(context, wizardResult);
77
- }
78
-
79
- if (process.argv.includes('--version') || process.argv.includes('-v')) {
80
- printVersionAndExit();
81
- }
82
-
83
- await maybeRunFirstRunWizard();
84
- const resolvedConfig = resolveAigentryConfig({ cwd: process.cwd() });
26
+ ensureUserLayout({ version: packageJson.version });
85
27
 
86
28
  if (!fs.existsSync(executable)) {
87
29
  console.error('[aterm] native app bundle is not installed');
@@ -89,6 +31,7 @@ if (!fs.existsSync(executable)) {
89
31
  process.exit(1);
90
32
  }
91
33
 
34
+ const resolvedConfig = resolveAigentryConfig({ cwd: process.cwd() });
92
35
  for (const warning of resolvedConfig.warnings) {
93
36
  console.warn(warning);
94
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aterm",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Native aterm launcher package",
5
5
  "type": "module",
6
6
  "main": "./bin/aterm.js",
@@ -17,15 +17,13 @@
17
17
  "package.json"
18
18
  ],
19
19
  "optionalDependencies": {
20
- "@dmsdc-ai/aterm-darwin-arm64": "0.1.12"
20
+ "@dmsdc-ai/aterm-darwin-arm64": "0.1.14"
21
21
  },
22
22
  "dependencies": {
23
23
  "@dmsdc-ai/aigentry-brain": "latest",
24
24
  "@dmsdc-ai/aigentry-deliberation": "latest",
25
25
  "@dmsdc-ai/aigentry-devkit": "latest",
26
- "@dmsdc-ai/aigentry-telepty": "latest",
27
- "blessed": "^0.1.81",
28
- "prompts": "^2.4.2"
26
+ "@dmsdc-ai/aigentry-telepty": "latest"
29
27
  },
30
28
  "license": "UNLICENSED",
31
29
  "publishConfig": {
@@ -1,311 +0,0 @@
1
- import path from 'node:path';
2
- import { createRequire } from 'node:module';
3
- import {
4
- detectAiCliStatus,
5
- resolveInstallHomeDir,
6
- resolveProjectRoot,
7
- updateConfigFile,
8
- } from '../lib/aigentry.js';
9
-
10
- const require = createRequire(import.meta.url);
11
-
12
- function waitForKeypress(screen, keys = ['enter', 'space', 'escape']) {
13
- return new Promise((resolve) => {
14
- const handler = (_, key) => {
15
- if (!key || !keys.includes(key.name)) {
16
- return;
17
- }
18
- screen.off('keypress', handler);
19
- resolve();
20
- };
21
- screen.on('keypress', handler);
22
- });
23
- }
24
-
25
- async function showInfoScreen(blessed, title, lines, footer) {
26
- const screen = blessed.screen({
27
- smartCSR: true,
28
- title: 'aterm installer',
29
- fullUnicode: true,
30
- });
31
-
32
- blessed.box({
33
- parent: screen,
34
- top: 'center',
35
- left: 'center',
36
- width: '78%',
37
- height: Math.max(12, lines.length + 6),
38
- border: { type: 'line' },
39
- tags: true,
40
- label: ` ${title} `,
41
- style: {
42
- border: { fg: 'cyan' },
43
- fg: 'white',
44
- },
45
- content: `${lines.join('\n')}\n\n${footer}`,
46
- });
47
-
48
- screen.render();
49
- await waitForKeypress(screen);
50
- screen.destroy();
51
- // Reset terminal modes that blessed may leave set (DECCKM, keypad)
52
- // so that subsequent prompts receive normal arrow key sequences.
53
- process.stdout.write('\x1b[?1l\x1b>');
54
- }
55
-
56
- function buildWorkspaceChoices(context) {
57
- const choices = [];
58
- if (context.orchestratorAvailable) {
59
- choices.push({
60
- title: 'aigentry-orchestrator',
61
- value: 'orchestrator',
62
- description: context.orchestratorPath,
63
- });
64
- }
65
-
66
- if (context.projectRoot) {
67
- choices.push({
68
- title: 'current project',
69
- value: 'project',
70
- description: context.projectRoot,
71
- });
72
- }
73
-
74
- choices.push({
75
- title: 'home directory',
76
- value: 'home',
77
- description: resolveInstallHomeDir(),
78
- });
79
-
80
- return choices;
81
- }
82
-
83
- function buildConfigPatch(context, answers) {
84
- const workspacePathMap = {
85
- orchestrator: context.orchestratorPath,
86
- project: context.projectRoot,
87
- home: resolveInstallHomeDir(),
88
- };
89
-
90
- return {
91
- shell: {
92
- default: answers.defaultShell,
93
- },
94
- workspace: {
95
- default: answers.defaultWorkspace,
96
- path: workspacePathMap[answers.defaultWorkspace] ?? resolveInstallHomeDir(),
97
- },
98
- orchestrator: {
99
- enabled: answers.defaultWorkspace === 'orchestrator',
100
- path: context.orchestratorPath,
101
- },
102
- tailscale: {
103
- connect_on_launch: answers.tailscaleConnect,
104
- },
105
- ai: {
106
- defaultCLI: answers.defaultCLI,
107
- detected_clis: context.cliStatus,
108
- },
109
- };
110
- }
111
-
112
- export async function runFirstRunWizard(context) {
113
- const blessed = require('blessed');
114
- const prompts = (await import('prompts')).default;
115
-
116
- await showInfoScreen(
117
- blessed,
118
- ' aterm Installer ',
119
- [
120
- '{center}{bold}Aigentry Terminal Installer{/bold}{/center}',
121
- '',
122
- 'This wizard finishes your aterm setup before the native app launches.',
123
- 'It will save your preferred shell, workspace, and Tailscale defaults.',
124
- '',
125
- `Package version: ${context.version}`,
126
- ],
127
- '{gray-fg}Press Enter to continue{/}',
128
- );
129
-
130
- const cliLines = [
131
- '{bold}AI CLI detection{/bold}',
132
- '',
133
- `claude ${context.cliStatus.claude ? '✅' : '❌'}`,
134
- `codex ${context.cliStatus.codex ? '✅' : '❌'}`,
135
- `gemini ${context.cliStatus.gemini ? '✅' : '❌'}`,
136
- ];
137
-
138
- await showInfoScreen(
139
- blessed,
140
- ' CLI Status ',
141
- cliLines,
142
- '{gray-fg}Press Enter to continue{/}',
143
- );
144
-
145
- const workspaceChoices = buildWorkspaceChoices(context);
146
- const defaultResponses = {
147
- defaultShell: 'zsh',
148
- defaultWorkspace: workspaceChoices[0]?.value ?? 'home',
149
- defaultCLI: context.cliStatus.claude ? 'claude' : context.cliStatus.codex ? 'codex' : context.cliStatus.gemini ? 'gemini' : 'none',
150
- tailscaleConnect: false,
151
- };
152
- let cancelled = false;
153
-
154
- const responses = await prompts(
155
- [
156
- {
157
- type: 'select',
158
- name: 'defaultShell',
159
- message: 'Default shell',
160
- choices: [
161
- { title: 'zsh', value: 'zsh' },
162
- { title: 'bash', value: 'bash' },
163
- { title: 'fish', value: 'fish' },
164
- ],
165
- initial: 0,
166
- },
167
- {
168
- type: 'select',
169
- name: 'defaultWorkspace',
170
- message: 'Default workspace / orchestrator target',
171
- choices: workspaceChoices,
172
- initial: 0,
173
- },
174
- {
175
- type: 'select',
176
- name: 'defaultCLI',
177
- message: 'Default AI CLI for orchestrator workspace',
178
- choices: [
179
- { title: 'claude', value: 'claude', disabled: !context.cliStatus.claude },
180
- { title: 'codex', value: 'codex', disabled: !context.cliStatus.codex },
181
- { title: 'gemini', value: 'gemini', disabled: !context.cliStatus.gemini },
182
- { title: 'none (plain zsh)', value: 'none' },
183
- ],
184
- initial: context.cliStatus.claude ? 0 : context.cliStatus.codex ? 1 : context.cliStatus.gemini ? 2 : 3,
185
- },
186
- {
187
- type: 'toggle',
188
- name: 'tailscaleConnect',
189
- message: 'Enable Tailscale connect on launch?',
190
- initial: false,
191
- active: 'yes',
192
- inactive: 'no',
193
- },
194
- ],
195
- {
196
- onCancel: () => {
197
- cancelled = true;
198
- return false;
199
- },
200
- },
201
- );
202
-
203
- if (cancelled) {
204
- return null;
205
- }
206
-
207
- const mergedAnswers = {
208
- ...defaultResponses,
209
- ...responses,
210
- };
211
-
212
- return {
213
- configPatch: buildConfigPatch(context, mergedAnswers),
214
- summary: mergedAnswers,
215
- };
216
- }
217
-
218
- export function shouldRunFirstRunWizard() {
219
- if (process.env.CI) {
220
- return false;
221
- }
222
- if (process.env.npm_config_yes === 'true') {
223
- return false;
224
- }
225
- return Boolean(process.stdin.isTTY && process.stdout.isTTY);
226
- }
227
-
228
- export function buildFirstRunWizardContext(version, cwd = process.cwd()) {
229
- const installHome = resolveInstallHomeDir();
230
- const projectRoot = resolveProjectRoot(cwd);
231
- const orchestratorPath = path.join(installHome, 'projects', 'aigentry-orchestrator');
232
- const cliStatus = detectAiCliStatus(installHome);
233
-
234
- return {
235
- version,
236
- projectRoot,
237
- cliStatus,
238
- orchestratorPath,
239
- orchestratorAvailable: require('node:fs').existsSync(orchestratorPath),
240
- userConfigPath: path.join(installHome, '.aigentry', 'config', 'aterm.json'),
241
- };
242
- }
243
-
244
- export async function showProgressScreen(runSteps) {
245
- const blessed = require('blessed');
246
- const screen = blessed.screen({
247
- smartCSR: true,
248
- title: 'aterm installer',
249
- fullUnicode: true,
250
- });
251
-
252
- const box = blessed.log({
253
- parent: screen,
254
- top: 'center',
255
- left: 'center',
256
- width: '84%',
257
- height: '70%',
258
- border: { type: 'line' },
259
- tags: true,
260
- label: ' Installation Progress ',
261
- style: {
262
- border: { fg: 'green' },
263
- fg: 'white',
264
- },
265
- scrollable: true,
266
- alwaysScroll: true,
267
- scrollbar: { ch: ' ', inverse: true },
268
- });
269
-
270
- const report = (line) => {
271
- box.add(line);
272
- screen.render();
273
- };
274
-
275
- screen.render();
276
- await runSteps(report);
277
- await new Promise(resolve => setTimeout(resolve, 250));
278
- screen.destroy();
279
- process.stdout.write('\x1b[?1l\x1b>');
280
- }
281
-
282
- export async function showDoneScreen(summaryLines) {
283
- const blessed = require('blessed');
284
- await showInfoScreen(
285
- blessed,
286
- ' Install Complete ',
287
- summaryLines,
288
- '{green-fg}Run: aterm{/}',
289
- );
290
- }
291
-
292
- export async function completeFirstRunWizard(context, wizardResult) {
293
- const blessed = require('blessed');
294
- await showProgressScreen(async (progress) => {
295
- progress('{bold}Saving setup{/bold}');
296
- updateConfigFile(context.userConfigPath, {
297
- ...wizardResult.configPatch,
298
- setupCompleted: true,
299
- });
300
- progress(`{green-fg}ok{/} ${context.userConfigPath}`);
301
- });
302
-
303
- await showDoneScreen([
304
- 'aterm setup is complete.',
305
- '',
306
- `Shell: ${wizardResult.summary.defaultShell}`,
307
- `AI CLI: ${wizardResult.summary.defaultCLI}`,
308
- `Workspace: ${wizardResult.summary.defaultWorkspace}`,
309
- `Tailscale connect: ${wizardResult.summary.tailscaleConnect ? 'yes' : 'no'}`,
310
- ]);
311
- }