@zhigang1992/happy-cli 0.12.1 → 0.12.4
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/dist/{index-DsHtmQqP.mjs → index-BERBU6rR.mjs} +201 -23
- package/dist/{index-BOBrKhX5.cjs → index-CHEjP0zg.cjs} +215 -37
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +6 -6
- package/dist/lib.cjs +1 -2
- package/dist/lib.d.cts +118 -4
- package/dist/lib.d.mts +118 -4
- package/dist/lib.mjs +1 -2
- package/dist/{list-hET5tyMc.mjs → list-BvtUKVTq.mjs} +1 -1
- package/dist/{list-BW6QBLa1.cjs → list-DOsBjFRJ.cjs} +1 -1
- package/dist/{prompt-Dz7G8yGx.mjs → prompt-BbMNN7fl.mjs} +1 -2
- package/dist/{prompt-DXkgjktW.cjs → prompt-Dh_trad0.cjs} +1 -2
- package/dist/{runCodex-CLGYMNs2.mjs → runCodex-CYkmZphO.mjs} +20 -4
- package/dist/{runCodex-CylcX5Ug.cjs → runCodex-DUqqO-m8.cjs} +20 -4
- package/dist/{types-CGco5Y-r.mjs → types-Cw6y7GyQ.mjs} +156 -20
- package/dist/{types-BsjUgWOx.cjs → types-Q-euvEmG.cjs} +154 -18
- package/package.json +2 -4
- package/scripts/download-tool.cjs +187 -0
- package/scripts/ripgrep_launcher.cjs +53 -2
- package/scripts/tools-config.cjs +119 -0
- package/tools/archives/difftastic-LICENSE +0 -21
- package/tools/archives/difftastic-arm64-darwin.tar.gz +0 -0
- package/tools/archives/difftastic-arm64-linux.tar.gz +0 -0
- package/tools/archives/difftastic-x64-darwin.tar.gz +0 -0
- package/tools/archives/difftastic-x64-linux.tar.gz +0 -0
- package/tools/archives/difftastic-x64-win32.tar.gz +0 -0
- package/tools/archives/ripgrep-LICENSE +0 -3
- package/tools/archives/ripgrep-arm64-darwin.tar.gz +0 -0
- package/tools/archives/ripgrep-arm64-linux.tar.gz +0 -0
- package/tools/archives/ripgrep-x64-darwin.tar.gz +0 -0
- package/tools/archives/ripgrep-x64-linux.tar.gz +0 -0
- package/tools/archives/ripgrep-x64-win32.tar.gz +0 -0
- package/tools/licenses/difftastic-LICENSE +0 -21
- package/tools/licenses/ripgrep-LICENSE +0 -3
- package/tools/unpacked/difft +0 -0
- package/tools/unpacked/rg +0 -0
- package/tools/unpacked/ripgrep.node +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Downloads and extracts a tool binary on first use
|
|
5
|
+
* Usage: node download-tool.cjs <toolName>
|
|
6
|
+
*
|
|
7
|
+
* This script is designed to be called before using a tool.
|
|
8
|
+
* It's idempotent - if the tool is already downloaded, it does nothing.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const https = require('https');
|
|
15
|
+
const { createGunzip } = require('zlib');
|
|
16
|
+
const { pipeline } = require('stream/promises');
|
|
17
|
+
const { getDownloadUrl, getBinaryName, getToolPath, TOOLS } = require('./tools-config.cjs');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Follow redirects and download a file
|
|
21
|
+
*/
|
|
22
|
+
function downloadFile(url, destPath, maxRedirects = 5) {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
if (maxRedirects <= 0) {
|
|
25
|
+
reject(new Error('Too many redirects'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const protocol = url.startsWith('https') ? https : require('http');
|
|
30
|
+
|
|
31
|
+
protocol.get(url, (response) => {
|
|
32
|
+
// Handle redirects
|
|
33
|
+
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
34
|
+
downloadFile(response.headers.location, destPath, maxRedirects - 1)
|
|
35
|
+
.then(resolve)
|
|
36
|
+
.catch(reject);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (response.statusCode !== 200) {
|
|
41
|
+
reject(new Error(`Download failed with status ${response.statusCode}`));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const fileStream = fs.createWriteStream(destPath);
|
|
46
|
+
response.pipe(fileStream);
|
|
47
|
+
|
|
48
|
+
fileStream.on('finish', () => {
|
|
49
|
+
fileStream.close();
|
|
50
|
+
resolve();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
fileStream.on('error', (err) => {
|
|
54
|
+
fs.unlink(destPath, () => {}); // Clean up partial file
|
|
55
|
+
reject(err);
|
|
56
|
+
});
|
|
57
|
+
}).on('error', reject);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Extract a tar.gz file
|
|
63
|
+
*/
|
|
64
|
+
async function extractTarGz(archivePath, destDir, toolName) {
|
|
65
|
+
const tar = require('tar');
|
|
66
|
+
const tool = TOOLS[toolName];
|
|
67
|
+
|
|
68
|
+
await tar.extract({
|
|
69
|
+
file: archivePath,
|
|
70
|
+
cwd: destDir,
|
|
71
|
+
filter: (entryPath) => {
|
|
72
|
+
// Only extract the binary we need
|
|
73
|
+
const binaryName = getBinaryName(toolName, os.platform());
|
|
74
|
+
return entryPath.endsWith(binaryName);
|
|
75
|
+
},
|
|
76
|
+
strip: tool.archiveStructure === 'nested' ? 1 : 0
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Extract a zip file (for Windows)
|
|
82
|
+
*/
|
|
83
|
+
async function extractZip(archivePath, destDir, toolName) {
|
|
84
|
+
const AdmZip = require('adm-zip');
|
|
85
|
+
const tool = TOOLS[toolName];
|
|
86
|
+
const binaryName = getBinaryName(toolName, os.platform());
|
|
87
|
+
|
|
88
|
+
const zip = new AdmZip(archivePath);
|
|
89
|
+
const entries = zip.getEntries();
|
|
90
|
+
|
|
91
|
+
for (const entry of entries) {
|
|
92
|
+
if (entry.entryName.endsWith(binaryName)) {
|
|
93
|
+
const content = entry.getData();
|
|
94
|
+
const destPath = path.join(destDir, binaryName);
|
|
95
|
+
fs.writeFileSync(destPath, content);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Ensure a tool is downloaded and available
|
|
103
|
+
*/
|
|
104
|
+
async function ensureTool(toolName) {
|
|
105
|
+
const tool = TOOLS[toolName];
|
|
106
|
+
if (!tool) {
|
|
107
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const platform = os.platform();
|
|
111
|
+
const arch = os.arch();
|
|
112
|
+
const toolPath = getToolPath(toolName);
|
|
113
|
+
|
|
114
|
+
// Check if already downloaded
|
|
115
|
+
if (fs.existsSync(toolPath)) {
|
|
116
|
+
return toolPath;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const toolDir = path.dirname(toolPath);
|
|
120
|
+
fs.mkdirSync(toolDir, { recursive: true });
|
|
121
|
+
|
|
122
|
+
// Get download URL
|
|
123
|
+
const url = getDownloadUrl(toolName, platform, arch);
|
|
124
|
+
const isZip = url.endsWith('.zip');
|
|
125
|
+
const archivePath = path.join(toolDir, `archive${isZip ? '.zip' : '.tar.gz'}`);
|
|
126
|
+
|
|
127
|
+
console.error(`[happy-cli] Downloading ${toolName} v${tool.version}...`);
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
// Download the archive
|
|
131
|
+
await downloadFile(url, archivePath);
|
|
132
|
+
|
|
133
|
+
// Extract
|
|
134
|
+
if (isZip) {
|
|
135
|
+
await extractZip(archivePath, toolDir, toolName);
|
|
136
|
+
} else {
|
|
137
|
+
await extractTarGz(archivePath, toolDir, toolName);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Set executable permission on Unix
|
|
141
|
+
if (platform !== 'win32') {
|
|
142
|
+
fs.chmodSync(toolPath, 0o755);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Clean up archive
|
|
146
|
+
fs.unlinkSync(archivePath);
|
|
147
|
+
|
|
148
|
+
console.error(`[happy-cli] ${toolName} v${tool.version} installed to ${toolPath}`);
|
|
149
|
+
return toolPath;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
// Clean up on failure
|
|
152
|
+
try {
|
|
153
|
+
fs.unlinkSync(archivePath);
|
|
154
|
+
} catch {}
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Run a tool, downloading it first if necessary
|
|
161
|
+
* Returns the path to the binary
|
|
162
|
+
*/
|
|
163
|
+
async function getOrDownloadTool(toolName) {
|
|
164
|
+
return ensureTool(toolName);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// If run directly, download the specified tool
|
|
168
|
+
if (require.main === module) {
|
|
169
|
+
const toolName = process.argv[2];
|
|
170
|
+
if (!toolName) {
|
|
171
|
+
console.error('Usage: node download-tool.cjs <toolName>');
|
|
172
|
+
console.error('Available tools:', Object.keys(TOOLS).join(', '));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
ensureTool(toolName)
|
|
177
|
+
.then((toolPath) => {
|
|
178
|
+
// Output the path so callers can use it
|
|
179
|
+
console.log(toolPath);
|
|
180
|
+
})
|
|
181
|
+
.catch((error) => {
|
|
182
|
+
console.error(`Failed to download ${toolName}:`, error.message);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
module.exports = { ensureTool, getOrDownloadTool };
|
|
@@ -3,12 +3,63 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Ripgrep runner - executed as a subprocess to run the native module
|
|
5
5
|
* This file is intentionally written in CommonJS to avoid ESM complexities
|
|
6
|
+
*
|
|
7
|
+
* Uses the ripgrep.node native module bundled with @anthropic-ai/claude-code
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
10
|
const path = require('path');
|
|
11
|
+
const os = require('os');
|
|
12
|
+
const fs = require('fs');
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Get the platform-specific directory name for claude-code vendor
|
|
16
|
+
*/
|
|
17
|
+
function getPlatformDir() {
|
|
18
|
+
const platform = os.platform();
|
|
19
|
+
const arch = os.arch();
|
|
20
|
+
|
|
21
|
+
if (platform === 'darwin') {
|
|
22
|
+
return arch === 'arm64' ? 'arm64-darwin' : 'x64-darwin';
|
|
23
|
+
} else if (platform === 'linux') {
|
|
24
|
+
return arch === 'arm64' ? 'arm64-linux' : 'x64-linux';
|
|
25
|
+
} else if (platform === 'win32') {
|
|
26
|
+
return 'x64-win32';
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Find the ripgrep.node native module
|
|
33
|
+
* First checks claude-code vendor directory, falls back to local tools
|
|
34
|
+
*/
|
|
35
|
+
function findRipgrepModule() {
|
|
36
|
+
const platformDir = getPlatformDir();
|
|
37
|
+
|
|
38
|
+
// Try claude-code vendor first (preferred - it's always up to date)
|
|
39
|
+
const claudeCodePaths = [
|
|
40
|
+
// When installed as a dependency
|
|
41
|
+
path.join(__dirname, '..', 'node_modules', '@anthropic-ai', 'claude-code', 'vendor', 'ripgrep', platformDir, 'ripgrep.node'),
|
|
42
|
+
// When running from workspace root
|
|
43
|
+
path.join(__dirname, '..', '..', 'node_modules', '@anthropic-ai', 'claude-code', 'vendor', 'ripgrep', platformDir, 'ripgrep.node'),
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const modulePath of claudeCodePaths) {
|
|
47
|
+
if (fs.existsSync(modulePath)) {
|
|
48
|
+
return modulePath;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Fallback to local tools/unpacked (for development)
|
|
53
|
+
const localPath = path.join(__dirname, '..', 'tools', 'unpacked', 'ripgrep.node');
|
|
54
|
+
if (fs.existsSync(localPath)) {
|
|
55
|
+
return localPath;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw new Error('Could not find ripgrep.node native module. Make sure @anthropic-ai/claude-code is installed.');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Load the native module
|
|
62
|
+
const modulePath = findRipgrepModule();
|
|
12
63
|
const ripgrepNative = require(modulePath);
|
|
13
64
|
|
|
14
65
|
// Get arguments from command line (skip node and script name)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for external tool binaries
|
|
3
|
+
* These are downloaded on first use, not bundled with the package
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const TOOLS = {
|
|
7
|
+
difftastic: {
|
|
8
|
+
version: '0.64.0',
|
|
9
|
+
repo: 'Wilfred/difftastic',
|
|
10
|
+
// Map platform/arch to GitHub release asset names
|
|
11
|
+
assets: {
|
|
12
|
+
'darwin-arm64': 'difft-aarch64-apple-darwin.tar.gz',
|
|
13
|
+
'darwin-x64': 'difft-x86_64-apple-darwin.tar.gz',
|
|
14
|
+
'linux-arm64': 'difft-aarch64-unknown-linux-gnu.tar.gz',
|
|
15
|
+
'linux-x64': 'difft-x86_64-unknown-linux-gnu.tar.gz',
|
|
16
|
+
'win32-x64': 'difft-x86_64-pc-windows-msvc.zip',
|
|
17
|
+
},
|
|
18
|
+
// Binary name inside the archive (or after extraction)
|
|
19
|
+
binaryName: {
|
|
20
|
+
'win32': 'difft.exe',
|
|
21
|
+
'default': 'difft'
|
|
22
|
+
},
|
|
23
|
+
// Some archives have the binary in a subdirectory
|
|
24
|
+
archiveStructure: 'flat' // binary is at root of archive
|
|
25
|
+
},
|
|
26
|
+
ripgrep: {
|
|
27
|
+
version: '14.1.1',
|
|
28
|
+
repo: 'BurntSushi/ripgrep',
|
|
29
|
+
assets: {
|
|
30
|
+
'darwin-arm64': 'ripgrep-14.1.1-aarch64-apple-darwin.tar.gz',
|
|
31
|
+
'darwin-x64': 'ripgrep-14.1.1-x86_64-apple-darwin.tar.gz',
|
|
32
|
+
'linux-arm64': 'ripgrep-14.1.1-aarch64-unknown-linux-gnu.tar.gz',
|
|
33
|
+
'linux-x64': 'ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz',
|
|
34
|
+
'win32-x64': 'ripgrep-14.1.1-x86_64-pc-windows-msvc.zip',
|
|
35
|
+
},
|
|
36
|
+
binaryName: {
|
|
37
|
+
'win32': 'rg.exe',
|
|
38
|
+
'default': 'rg'
|
|
39
|
+
},
|
|
40
|
+
// ripgrep archives have files in a subdirectory named after the archive
|
|
41
|
+
archiveStructure: 'nested' // binary is in a subdirectory
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get download URL for a tool
|
|
47
|
+
*/
|
|
48
|
+
function getDownloadUrl(toolName, platform, arch) {
|
|
49
|
+
const tool = TOOLS[toolName];
|
|
50
|
+
if (!tool) {
|
|
51
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const key = `${platform}-${arch}`;
|
|
55
|
+
const asset = tool.assets[key];
|
|
56
|
+
if (!asset) {
|
|
57
|
+
throw new Error(`Unsupported platform for ${toolName}: ${key}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return `https://github.com/${tool.repo}/releases/download/${tool.version}/${asset}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get binary name for a tool on the current platform
|
|
65
|
+
*/
|
|
66
|
+
function getBinaryName(toolName, platform) {
|
|
67
|
+
const tool = TOOLS[toolName];
|
|
68
|
+
if (!tool) {
|
|
69
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return tool.binaryName[platform] || tool.binaryName['default'];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get cache directory for tools
|
|
77
|
+
* Uses ~/.cache/happy-cli/tools on Unix, %LOCALAPPDATA%/happy-cli/tools on Windows
|
|
78
|
+
*/
|
|
79
|
+
function getCacheDir() {
|
|
80
|
+
const os = require('os');
|
|
81
|
+
const path = require('path');
|
|
82
|
+
|
|
83
|
+
const platform = os.platform();
|
|
84
|
+
const homeDir = os.homedir();
|
|
85
|
+
|
|
86
|
+
if (platform === 'win32') {
|
|
87
|
+
const localAppData = process.env.LOCALAPPDATA || path.join(homeDir, 'AppData', 'Local');
|
|
88
|
+
return path.join(localAppData, 'happy-cli', 'tools');
|
|
89
|
+
} else {
|
|
90
|
+
const cacheHome = process.env.XDG_CACHE_HOME || path.join(homeDir, '.cache');
|
|
91
|
+
return path.join(cacheHome, 'happy-cli', 'tools');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get the expected path for a tool binary
|
|
97
|
+
*/
|
|
98
|
+
function getToolPath(toolName) {
|
|
99
|
+
const os = require('os');
|
|
100
|
+
const path = require('path');
|
|
101
|
+
|
|
102
|
+
const tool = TOOLS[toolName];
|
|
103
|
+
if (!tool) {
|
|
104
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const cacheDir = getCacheDir();
|
|
108
|
+
const binaryName = getBinaryName(toolName, os.platform());
|
|
109
|
+
|
|
110
|
+
return path.join(cacheDir, toolName, tool.version, binaryName);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
TOOLS,
|
|
115
|
+
getDownloadUrl,
|
|
116
|
+
getBinaryName,
|
|
117
|
+
getCacheDir,
|
|
118
|
+
getToolPath
|
|
119
|
+
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2021-2025 Wilfred Hughes
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2021-2025 Wilfred Hughes
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/tools/unpacked/difft
DELETED
|
Binary file
|
package/tools/unpacked/rg
DELETED
|
Binary file
|
|
Binary file
|