@saferun/cli 0.5.26 → 0.5.28
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/commands/doctor.d.ts +18 -0
- package/dist/commands/doctor.js +439 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/setup.d.ts +47 -0
- package/dist/commands/setup.js +528 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/register-commands.js +27 -0
- package/dist/register-commands.js.map +1 -1
- package/dist/utils/credentials.d.ts +48 -0
- package/dist/utils/credentials.js +143 -0
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/gitignore.d.ts +22 -0
- package/dist/utils/gitignore.js +105 -0
- package/dist/utils/gitignore.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global credentials management for SafeRun
|
|
3
|
+
* Stores API key in ~/.saferun/credentials with secure permissions
|
|
4
|
+
*/
|
|
5
|
+
export interface GlobalCredentials {
|
|
6
|
+
api_key?: string;
|
|
7
|
+
created_at?: string;
|
|
8
|
+
updated_at?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Ensure global config directory exists with secure permissions
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureGlobalConfigDir(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Load credentials from global config
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadGlobalCredentials(): Promise<GlobalCredentials>;
|
|
18
|
+
/**
|
|
19
|
+
* Save credentials to global config with secure permissions
|
|
20
|
+
*/
|
|
21
|
+
export declare function saveGlobalCredentials(credentials: GlobalCredentials): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Get API key from (in order of priority):
|
|
24
|
+
* 1. Environment variable SAFERUN_API_KEY
|
|
25
|
+
* 2. Global credentials file ~/.saferun/credentials
|
|
26
|
+
* 3. Local config file .saferun/config.yml
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveApiKey(localApiKey?: string): Promise<string | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if API key is configured anywhere
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasApiKey(): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Validate API key format
|
|
35
|
+
*/
|
|
36
|
+
export declare function isValidApiKeyFormat(key: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Mask API key for display (show first 8 and last 4 chars)
|
|
39
|
+
*/
|
|
40
|
+
export declare function maskApiKey(key: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Get global config directory path
|
|
43
|
+
*/
|
|
44
|
+
export declare function getGlobalConfigDir(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Get credentials file path
|
|
47
|
+
*/
|
|
48
|
+
export declare function getCredentialsPath(): string;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Global credentials management for SafeRun
|
|
4
|
+
* Stores API key in ~/.saferun/credentials with secure permissions
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ensureGlobalConfigDir = ensureGlobalConfigDir;
|
|
11
|
+
exports.loadGlobalCredentials = loadGlobalCredentials;
|
|
12
|
+
exports.saveGlobalCredentials = saveGlobalCredentials;
|
|
13
|
+
exports.resolveApiKey = resolveApiKey;
|
|
14
|
+
exports.hasApiKey = hasApiKey;
|
|
15
|
+
exports.isValidApiKeyFormat = isValidApiKeyFormat;
|
|
16
|
+
exports.maskApiKey = maskApiKey;
|
|
17
|
+
exports.getGlobalConfigDir = getGlobalConfigDir;
|
|
18
|
+
exports.getCredentialsPath = getCredentialsPath;
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
const os_1 = __importDefault(require("os"));
|
|
22
|
+
const GLOBAL_CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.saferun');
|
|
23
|
+
const CREDENTIALS_FILE = path_1.default.join(GLOBAL_CONFIG_DIR, 'credentials');
|
|
24
|
+
const GLOBAL_CONFIG_FILE = path_1.default.join(GLOBAL_CONFIG_DIR, 'config.yml');
|
|
25
|
+
/**
|
|
26
|
+
* Ensure global config directory exists with secure permissions
|
|
27
|
+
*/
|
|
28
|
+
async function ensureGlobalConfigDir() {
|
|
29
|
+
if (!fs_1.default.existsSync(GLOBAL_CONFIG_DIR)) {
|
|
30
|
+
await fs_1.default.promises.mkdir(GLOBAL_CONFIG_DIR, { mode: 0o700, recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load credentials from global config
|
|
35
|
+
*/
|
|
36
|
+
async function loadGlobalCredentials() {
|
|
37
|
+
try {
|
|
38
|
+
await ensureGlobalConfigDir();
|
|
39
|
+
if (!fs_1.default.existsSync(CREDENTIALS_FILE)) {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
const content = await fs_1.default.promises.readFile(CREDENTIALS_FILE, 'utf-8');
|
|
43
|
+
const credentials = {};
|
|
44
|
+
// Simple key=value format (not YAML to avoid dependencies)
|
|
45
|
+
for (const line of content.split('\n')) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
48
|
+
continue;
|
|
49
|
+
const [key, ...valueParts] = trimmed.split('=');
|
|
50
|
+
const value = valueParts.join('=').trim();
|
|
51
|
+
if (key === 'api_key' || key === 'SAFERUN_API_KEY') {
|
|
52
|
+
credentials.api_key = value;
|
|
53
|
+
}
|
|
54
|
+
else if (key === 'created_at') {
|
|
55
|
+
credentials.created_at = value;
|
|
56
|
+
}
|
|
57
|
+
else if (key === 'updated_at') {
|
|
58
|
+
credentials.updated_at = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return credentials;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Save credentials to global config with secure permissions
|
|
69
|
+
*/
|
|
70
|
+
async function saveGlobalCredentials(credentials) {
|
|
71
|
+
await ensureGlobalConfigDir();
|
|
72
|
+
const now = new Date().toISOString();
|
|
73
|
+
const existing = await loadGlobalCredentials();
|
|
74
|
+
const content = [
|
|
75
|
+
'# SafeRun Global Credentials',
|
|
76
|
+
'# This file contains sensitive data - DO NOT COMMIT',
|
|
77
|
+
`# Created: ${existing.created_at || now}`,
|
|
78
|
+
`# Updated: ${now}`,
|
|
79
|
+
'',
|
|
80
|
+
`api_key=${credentials.api_key || ''}`,
|
|
81
|
+
`created_at=${existing.created_at || now}`,
|
|
82
|
+
`updated_at=${now}`,
|
|
83
|
+
'',
|
|
84
|
+
].join('\n');
|
|
85
|
+
await fs_1.default.promises.writeFile(CREDENTIALS_FILE, content, { mode: 0o600 });
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get API key from (in order of priority):
|
|
89
|
+
* 1. Environment variable SAFERUN_API_KEY
|
|
90
|
+
* 2. Global credentials file ~/.saferun/credentials
|
|
91
|
+
* 3. Local config file .saferun/config.yml
|
|
92
|
+
*/
|
|
93
|
+
async function resolveApiKey(localApiKey) {
|
|
94
|
+
// 1. Environment variable has highest priority
|
|
95
|
+
if (process.env.SAFERUN_API_KEY) {
|
|
96
|
+
return process.env.SAFERUN_API_KEY;
|
|
97
|
+
}
|
|
98
|
+
// 2. Global credentials
|
|
99
|
+
const globalCreds = await loadGlobalCredentials();
|
|
100
|
+
if (globalCreds.api_key) {
|
|
101
|
+
return globalCreds.api_key;
|
|
102
|
+
}
|
|
103
|
+
// 3. Local config (passed in)
|
|
104
|
+
if (localApiKey) {
|
|
105
|
+
return localApiKey;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if API key is configured anywhere
|
|
111
|
+
*/
|
|
112
|
+
async function hasApiKey() {
|
|
113
|
+
const key = await resolveApiKey();
|
|
114
|
+
return !!key;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Validate API key format
|
|
118
|
+
*/
|
|
119
|
+
function isValidApiKeyFormat(key) {
|
|
120
|
+
// SafeRun API keys start with 'sr_' and are at least 20 chars
|
|
121
|
+
return key.startsWith('sr_') && key.length >= 20;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Mask API key for display (show first 8 and last 4 chars)
|
|
125
|
+
*/
|
|
126
|
+
function maskApiKey(key) {
|
|
127
|
+
if (key.length < 16)
|
|
128
|
+
return '***';
|
|
129
|
+
return `${key.substring(0, 8)}...${key.substring(key.length - 4)}`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get global config directory path
|
|
133
|
+
*/
|
|
134
|
+
function getGlobalConfigDir() {
|
|
135
|
+
return GLOBAL_CONFIG_DIR;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get credentials file path
|
|
139
|
+
*/
|
|
140
|
+
function getCredentialsPath() {
|
|
141
|
+
return CREDENTIALS_FILE;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/utils/credentials.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAmBH,sDAIC;AAKD,sDAgCC;AAKD,sDAmBC;AAQD,sCAkBC;AAKD,8BAGC;AAKD,kDAGC;AAKD,gCAGC;AAKD,gDAEC;AAKD,gDAEC;AAlJD,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,MAAM,iBAAiB,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC9D,MAAM,gBAAgB,GAAG,cAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;AACrE,MAAM,kBAAkB,GAAG,cAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;AAQtE;;GAEG;AACI,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACtC,MAAM,YAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC;QACH,MAAM,qBAAqB,EAAE,CAAC;QAE9B,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACtE,MAAM,WAAW,GAAsB,EAAE,CAAC;QAE1C,2DAA2D;QAC3D,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAElD,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAE1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;gBACnD,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;YAC9B,CAAC;iBAAM,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBAChC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC;YACjC,CAAC;iBAAM,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBAChC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC;YACjC,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,qBAAqB,CAAC,WAA8B;IACxE,MAAM,qBAAqB,EAAE,CAAC;IAE9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAE/C,MAAM,OAAO,GAAG;QACd,8BAA8B;QAC9B,qDAAqD;QACrD,cAAc,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE;QAC1C,cAAc,GAAG,EAAE;QACnB,EAAE;QACF,WAAW,WAAW,CAAC,OAAO,IAAI,EAAE,EAAE;QACtC,cAAc,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE;QAC1C,cAAc,GAAG,EAAE;QACnB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,aAAa,CAAC,WAAoB;IACtD,+CAA+C;IAC/C,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACrC,CAAC;IAED,wBAAwB;IACxB,MAAM,WAAW,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAClD,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,8BAA8B;IAC9B,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,SAAS;IAC7B,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;IAClC,OAAO,CAAC,CAAC,GAAG,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,8DAA8D;IAC9D,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .gitignore management for SafeRun
|
|
3
|
+
* Ensures sensitive files are never committed
|
|
4
|
+
*/
|
|
5
|
+
export interface GitignoreCheckResult {
|
|
6
|
+
exists: boolean;
|
|
7
|
+
hasSaferunEntries: boolean;
|
|
8
|
+
missingEntries: string[];
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Check if .gitignore exists and has SafeRun entries
|
|
13
|
+
*/
|
|
14
|
+
export declare function checkGitignore(repoRoot: string): Promise<GitignoreCheckResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Add SafeRun entries to .gitignore
|
|
17
|
+
*/
|
|
18
|
+
export declare function addToGitignore(repoRoot: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the entries that would be added to .gitignore
|
|
21
|
+
*/
|
|
22
|
+
export declare function getSaferunGitignoreEntries(): string[];
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* .gitignore management for SafeRun
|
|
4
|
+
* Ensures sensitive files are never committed
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.checkGitignore = checkGitignore;
|
|
11
|
+
exports.addToGitignore = addToGitignore;
|
|
12
|
+
exports.getSaferunGitignoreEntries = getSaferunGitignoreEntries;
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const SAFERUN_GITIGNORE_ENTRIES = [
|
|
16
|
+
'',
|
|
17
|
+
'# SafeRun - security (never commit credentials)',
|
|
18
|
+
'.saferun/credentials',
|
|
19
|
+
'.saferun/secrets/',
|
|
20
|
+
'',
|
|
21
|
+
'# SafeRun - local cache and logs',
|
|
22
|
+
'.saferun/cache/',
|
|
23
|
+
'.saferun/*.log',
|
|
24
|
+
'.saferun/logs/',
|
|
25
|
+
];
|
|
26
|
+
const REQUIRED_ENTRIES = [
|
|
27
|
+
'.saferun/credentials',
|
|
28
|
+
'.saferun/secrets/',
|
|
29
|
+
'.saferun/cache/',
|
|
30
|
+
'.saferun/*.log',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Check if .gitignore exists and has SafeRun entries
|
|
34
|
+
*/
|
|
35
|
+
async function checkGitignore(repoRoot) {
|
|
36
|
+
const gitignorePath = path_1.default.join(repoRoot, '.gitignore');
|
|
37
|
+
const result = {
|
|
38
|
+
exists: false,
|
|
39
|
+
hasSaferunEntries: false,
|
|
40
|
+
missingEntries: [],
|
|
41
|
+
path: gitignorePath,
|
|
42
|
+
};
|
|
43
|
+
if (!fs_1.default.existsSync(gitignorePath)) {
|
|
44
|
+
result.missingEntries = [...REQUIRED_ENTRIES];
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
result.exists = true;
|
|
48
|
+
try {
|
|
49
|
+
const content = await fs_1.default.promises.readFile(gitignorePath, 'utf-8');
|
|
50
|
+
const lines = content.split('\n').map(l => l.trim());
|
|
51
|
+
// Check each required entry
|
|
52
|
+
for (const entry of REQUIRED_ENTRIES) {
|
|
53
|
+
const found = lines.some(line => {
|
|
54
|
+
// Exact match or pattern match
|
|
55
|
+
if (line === entry)
|
|
56
|
+
return true;
|
|
57
|
+
// Check if .saferun/ is ignored entirely
|
|
58
|
+
if (line === '.saferun/' || line === '.saferun')
|
|
59
|
+
return true;
|
|
60
|
+
// Check glob patterns
|
|
61
|
+
if (entry.includes('*') && line === entry)
|
|
62
|
+
return true;
|
|
63
|
+
return false;
|
|
64
|
+
});
|
|
65
|
+
if (!found) {
|
|
66
|
+
result.missingEntries.push(entry);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
result.hasSaferunEntries = result.missingEntries.length === 0;
|
|
70
|
+
// Also check if entire .saferun is ignored (that's fine too)
|
|
71
|
+
if (lines.includes('.saferun/') || lines.includes('.saferun')) {
|
|
72
|
+
result.hasSaferunEntries = true;
|
|
73
|
+
result.missingEntries = [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
result.missingEntries = [...REQUIRED_ENTRIES];
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Add SafeRun entries to .gitignore
|
|
83
|
+
*/
|
|
84
|
+
async function addToGitignore(repoRoot) {
|
|
85
|
+
const gitignorePath = path_1.default.join(repoRoot, '.gitignore');
|
|
86
|
+
let content = '';
|
|
87
|
+
if (fs_1.default.existsSync(gitignorePath)) {
|
|
88
|
+
content = await fs_1.default.promises.readFile(gitignorePath, 'utf-8');
|
|
89
|
+
// Ensure file ends with newline
|
|
90
|
+
if (!content.endsWith('\n')) {
|
|
91
|
+
content += '\n';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Add SafeRun section
|
|
95
|
+
content += SAFERUN_GITIGNORE_ENTRIES.join('\n');
|
|
96
|
+
content += '\n';
|
|
97
|
+
await fs_1.default.promises.writeFile(gitignorePath, content);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the entries that would be added to .gitignore
|
|
101
|
+
*/
|
|
102
|
+
function getSaferunGitignoreEntries() {
|
|
103
|
+
return [...SAFERUN_GITIGNORE_ENTRIES];
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=gitignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/utils/gitignore.ts"],"names":[],"mappings":"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"}
|