termify-agent 1.0.29 → 1.0.30
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.
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "termify-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
4
4
|
"description": "Termify Agent CLI - Connect your local terminal to Termify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,13 +33,15 @@
|
|
|
33
33
|
"chalk": "^5.3.0",
|
|
34
34
|
"commander": "^12.0.0",
|
|
35
35
|
"conf": "^12.0.0",
|
|
36
|
-
"node-pty": "^1.1.0",
|
|
37
36
|
"open": "^10.0.0",
|
|
38
37
|
"ora": "^8.0.1",
|
|
39
38
|
"simple-git": "^3.30.0",
|
|
40
|
-
"ssh2": "^1.15.0",
|
|
41
39
|
"ws": "^8.16.0"
|
|
42
40
|
},
|
|
41
|
+
"optionalDependencies": {
|
|
42
|
+
"node-pty": "^1.1.0",
|
|
43
|
+
"ssh2": "^1.15.0"
|
|
44
|
+
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@types/node": "^20.11.0",
|
|
45
47
|
"@types/ssh2": "^1.15.0",
|
package/scripts/postinstall.js
CHANGED
|
@@ -31,30 +31,29 @@ const STATS_AGENT_PATH = join(TERMIFY_DIR, `stats-agent${EXE}`);
|
|
|
31
31
|
const MCP_DIR = join(TERMIFY_DIR, 'termify-mcp');
|
|
32
32
|
const MCP_BUNDLE_PATH = join(MCP_DIR, 'index.mjs');
|
|
33
33
|
|
|
34
|
+
// Marker: skip node-pty test on repeated installs if it already works for this ABI
|
|
35
|
+
const NODE_PTY_OK_MARKER = join(TERMIFY_DIR, `.node-pty-ok-${process.versions.modules}`);
|
|
36
|
+
|
|
34
37
|
/**
|
|
35
|
-
* Test if node-pty actually works by spawning a shell
|
|
38
|
+
* Test if node-pty actually works by spawning a shell in a child process.
|
|
39
|
+
* Uses child process to isolate potential SIGSEGV from bad prebuilds.
|
|
36
40
|
*/
|
|
37
41
|
function testNodePty() {
|
|
42
|
+
// Fast path: marker from previous successful install
|
|
43
|
+
if (existsSync(NODE_PTY_OK_MARKER)) return true;
|
|
44
|
+
|
|
38
45
|
try {
|
|
39
|
-
|
|
40
|
-
const pty = require('node-pty');
|
|
41
|
-
const term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : '/bin/sh', [], {
|
|
42
|
-
name: 'xterm-256color',
|
|
43
|
-
cols: 80,
|
|
44
|
-
rows: 24,
|
|
45
|
-
cwd: process.env.HOME || process.env.USERPROFILE || '/',
|
|
46
|
-
env: process.env
|
|
47
|
-
});
|
|
48
|
-
term.kill();
|
|
49
|
-
process.exit(0);
|
|
50
|
-
`;
|
|
51
|
-
execSync(`node -e "${testScript.replace(/"/g, '\\"').replace(/\n/g, ' ')}"`, {
|
|
46
|
+
execSync('node -e "require(\'node-pty\').spawn(\'/bin/sh\',[],{cols:80,rows:24}).kill()"', {
|
|
52
47
|
stdio: 'pipe',
|
|
53
|
-
timeout:
|
|
48
|
+
timeout: 5000,
|
|
54
49
|
cwd: process.cwd(),
|
|
55
50
|
});
|
|
51
|
+
// Cache result for next install
|
|
52
|
+
mkdirSync(TERMIFY_DIR, { recursive: true });
|
|
53
|
+
try { writeFileSync(NODE_PTY_OK_MARKER, Date.now().toString()); } catch {}
|
|
56
54
|
return true;
|
|
57
|
-
} catch
|
|
55
|
+
} catch {
|
|
56
|
+
try { unlinkSync(NODE_PTY_OK_MARKER); } catch {}
|
|
58
57
|
return false;
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -77,21 +76,20 @@ function resolveNodePtyDir() {
|
|
|
77
76
|
* For Node.js v24+, prebuilds may not be compatible, so we compile from source
|
|
78
77
|
*/
|
|
79
78
|
function rebuildNodePty() {
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
// node-pty is an optional dependency — skip entirely if not installed
|
|
80
|
+
const nodePtyDir = resolveNodePtyDir();
|
|
81
|
+
if (!nodePtyDir) {
|
|
82
|
+
console.log('[termify-agent] node-pty not installed (optional), skipping PTY setup.');
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
82
85
|
|
|
83
|
-
//
|
|
86
|
+
// Fast path: already works (cached or live test)
|
|
84
87
|
if (testNodePty()) {
|
|
85
|
-
console.log('[termify-agent] node-pty is
|
|
88
|
+
console.log('[termify-agent] node-pty is working.');
|
|
86
89
|
return true;
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
if (!nodePtyDir) {
|
|
91
|
-
console.error('[termify-agent] CRITICAL: node-pty directory not found.');
|
|
92
|
-
console.error('[termify-agent] Manual fix: npm install node-pty --build-from-source');
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
92
|
+
console.log(`[termify-agent] Node.js version: ${process.version}`);
|
|
95
93
|
|
|
96
94
|
console.log(`[termify-agent] node-pty resolved at: ${nodePtyDir}`);
|
|
97
95
|
console.log('[termify-agent] node-pty prebuilt not working, attempting source rebuild...');
|
|
@@ -787,57 +785,95 @@ function ensureCodexInstructions() {
|
|
|
787
785
|
}
|
|
788
786
|
}
|
|
789
787
|
|
|
788
|
+
// ---------------------------------------------------------------------------
|
|
789
|
+
// Pretty CLI output (no external deps — runs during postinstall)
|
|
790
|
+
// ---------------------------------------------------------------------------
|
|
791
|
+
|
|
792
|
+
const CYAN = '\x1b[36m';
|
|
793
|
+
const GREEN = '\x1b[32m';
|
|
794
|
+
const YELLOW = '\x1b[33m';
|
|
795
|
+
const DIM = '\x1b[2m';
|
|
796
|
+
const BOLD = '\x1b[1m';
|
|
797
|
+
const RESET = '\x1b[0m';
|
|
798
|
+
const CHECK = `${GREEN}✔${RESET}`;
|
|
799
|
+
const WARN = `${YELLOW}⚠${RESET}`;
|
|
800
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
801
|
+
|
|
802
|
+
function createSpinner(text) {
|
|
803
|
+
let i = 0;
|
|
804
|
+
const id = setInterval(() => {
|
|
805
|
+
process.stdout.write(`\r ${CYAN}${SPINNER_FRAMES[i++ % SPINNER_FRAMES.length]}${RESET} ${text} `);
|
|
806
|
+
}, 80);
|
|
807
|
+
return {
|
|
808
|
+
succeed(msg) { clearInterval(id); process.stdout.write(`\r ${CHECK} ${msg || text} \n`); },
|
|
809
|
+
warn(msg) { clearInterval(id); process.stdout.write(`\r ${WARN} ${msg || text} \n`); },
|
|
810
|
+
update(t) { text = t; },
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Suppress verbose internal logs — only spinner UI shows
|
|
815
|
+
const _log = console.log;
|
|
816
|
+
const _warn = console.warn;
|
|
817
|
+
const _err = console.error;
|
|
818
|
+
function muteConsole() { console.log = () => {}; console.warn = () => {}; console.error = () => {}; }
|
|
819
|
+
function unmuteConsole() { console.log = _log; console.warn = _warn; console.error = _err; }
|
|
820
|
+
|
|
790
821
|
/**
|
|
791
822
|
* Main
|
|
792
823
|
*/
|
|
793
824
|
async function main() {
|
|
794
|
-
console.log('
|
|
795
|
-
console.log(`
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
825
|
+
console.log('');
|
|
826
|
+
console.log(` ${BOLD}${CYAN}Termify Agent${RESET} ${DIM}postinstall${RESET}`);
|
|
827
|
+
console.log(` ${DIM}${platform()}-${arch()} · Node ${process.version}${RESET}`);
|
|
828
|
+
console.log('');
|
|
829
|
+
|
|
830
|
+
muteConsole();
|
|
831
|
+
|
|
832
|
+
// Step 1: node-pty
|
|
833
|
+
const s1 = createSpinner('Checking node-pty...');
|
|
834
|
+
const ptyOk = rebuildNodePty();
|
|
835
|
+
if (ptyOk) s1.succeed('node-pty ready');
|
|
836
|
+
else s1.warn('node-pty skipped ${DIM}(optional)${RESET}');
|
|
837
|
+
|
|
838
|
+
// Step 2+3: Binaries in parallel
|
|
839
|
+
const s2 = createSpinner('Installing binaries...');
|
|
840
|
+
const [daemonOk, statsOk] = await Promise.all([
|
|
841
|
+
installDaemon().catch(() => false),
|
|
842
|
+
installStatsAgent().catch(() => false),
|
|
843
|
+
]);
|
|
844
|
+
const parts = [];
|
|
845
|
+
if (daemonOk) parts.push('daemon');
|
|
846
|
+
if (statsOk) parts.push('stats-agent');
|
|
847
|
+
if (parts.length) s2.succeed(`Binaries ready ${DIM}(${parts.join(', ')})${RESET}`);
|
|
848
|
+
else s2.warn('Binaries skipped');
|
|
849
|
+
|
|
850
|
+
// Step 3: MCP + hooks
|
|
851
|
+
const s3 = createSpinner('Configuring hooks & MCP...');
|
|
818
852
|
try {
|
|
819
853
|
installTermifyMcp();
|
|
854
|
+
s3.succeed(`Hooks & MCP configured ${DIM}(Claude · Gemini · Codex)${RESET}`);
|
|
820
855
|
} catch (err) {
|
|
821
|
-
|
|
856
|
+
s3.warn(`Hooks & MCP: ${err.message}`);
|
|
822
857
|
}
|
|
823
858
|
|
|
824
|
-
// Step
|
|
859
|
+
// Step 4: Instructions
|
|
860
|
+
const s4 = createSpinner('Updating AI instructions...');
|
|
825
861
|
try {
|
|
826
862
|
ensureClaudeInstructions();
|
|
827
|
-
} catch (err) {
|
|
828
|
-
console.warn(`[termify-agent] Warning: ${err.message}`);
|
|
829
|
-
}
|
|
830
|
-
try {
|
|
831
863
|
ensureCodexInstructions();
|
|
864
|
+
s4.succeed('AI instructions updated');
|
|
832
865
|
} catch (err) {
|
|
833
|
-
|
|
866
|
+
s4.warn(`Instructions: ${err.message}`);
|
|
834
867
|
}
|
|
835
868
|
|
|
836
|
-
|
|
869
|
+
unmuteConsole();
|
|
870
|
+
|
|
871
|
+
console.log('');
|
|
872
|
+
console.log(` ${GREEN}${BOLD}Done!${RESET} ${DIM}Termify Agent is ready.${RESET}`);
|
|
873
|
+
console.log('');
|
|
837
874
|
}
|
|
838
875
|
|
|
839
876
|
main().catch((err) => {
|
|
840
|
-
console.warn(
|
|
841
|
-
// Never fail the install - postinstall errors should be warnings only
|
|
877
|
+
console.warn(`\n ${WARN} Postinstall warning: ${err.message}\n`);
|
|
842
878
|
process.exit(0);
|
|
843
879
|
});
|