fullcourtdefense-cli 1.7.3 → 1.7.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.
|
@@ -626,12 +626,19 @@ async function discoverCommand(args, config) {
|
|
|
626
626
|
console.log('Removed daily desktop discovery schedule.');
|
|
627
627
|
return;
|
|
628
628
|
}
|
|
629
|
-
if (args.schedule === 'daily') {
|
|
629
|
+
if (args.schedule === 'daily' || args.schedule === 'logon') {
|
|
630
630
|
const hour = args.scheduleHour ? Number.parseInt(args.scheduleHour, 10) : 9;
|
|
631
|
-
|
|
631
|
+
const surface = surfaces.size === 4 ? 'all' : Array.from(surfaces).join(',');
|
|
632
|
+
(0, discoverSchedule_1.installDailyDiscoverSchedule)({
|
|
633
|
+
userEmail: args.userEmail,
|
|
634
|
+
hour: Number.isFinite(hour) ? hour : 9,
|
|
635
|
+
surface,
|
|
636
|
+
trigger: args.schedule,
|
|
637
|
+
});
|
|
632
638
|
if (!silent) {
|
|
633
|
-
|
|
634
|
-
console.log(
|
|
639
|
+
const when = args.schedule === 'logon' ? 'at logon' : `daily at ${String(Number.isFinite(hour) ? hour : 9).padStart(2, '0')}:00`;
|
|
640
|
+
console.log(`Desktop discovery scheduled ${when} (runs discover --surface ${surface} --upload --silent${args.userEmail ? ` --user-email ${args.userEmail}` : ''}).`);
|
|
641
|
+
console.log('Uses login Shield credentials or an explicit org API key.');
|
|
635
642
|
}
|
|
636
643
|
return;
|
|
637
644
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface ScheduleArgs {
|
|
2
2
|
userEmail?: string;
|
|
3
3
|
hour?: number;
|
|
4
|
+
surface?: string;
|
|
5
|
+
trigger?: 'daily' | 'logon';
|
|
4
6
|
}
|
|
5
7
|
export declare function installDailyDiscoverSchedule(args?: ScheduleArgs): void;
|
|
6
8
|
export declare function uninstallDailyDiscoverSchedule(): void;
|
|
@@ -40,33 +40,56 @@ const fs = __importStar(require("fs"));
|
|
|
40
40
|
const os = __importStar(require("os"));
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const TASK_NAME = 'FullCourtDefenseDesktopDiscover';
|
|
43
|
-
|
|
43
|
+
const STARTUP_LAUNCHER = 'FullCourtDefenseDesktopDiscover.cmd';
|
|
44
|
+
function windowsStartupLauncherPath() {
|
|
45
|
+
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
46
|
+
return path.join(appData, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup', STARTUP_LAUNCHER);
|
|
47
|
+
}
|
|
48
|
+
function discoverCommandLine(userEmail, surface) {
|
|
44
49
|
const node = process.execPath;
|
|
45
50
|
const script = path.resolve(process.argv[1] || path.join(__dirname, '..', 'index.js'));
|
|
46
51
|
const q = (value) => (/\s/.test(value) ? `"${value}"` : value);
|
|
47
52
|
const parts = [q(node), q(script), 'discover', '--upload', '--silent'];
|
|
53
|
+
if (surface)
|
|
54
|
+
parts.push('--surface', q(surface));
|
|
48
55
|
if (userEmail)
|
|
49
56
|
parts.push('--user-email', q(userEmail));
|
|
50
57
|
return parts.join(' ');
|
|
51
58
|
}
|
|
52
|
-
function installWindowsSchedule(hour, userEmail) {
|
|
53
|
-
const tr = discoverCommandLine(userEmail);
|
|
54
|
-
const st = `${String(hour).padStart(2, '0')}:00`;
|
|
59
|
+
function installWindowsSchedule(hour, userEmail, surface, trigger = 'daily') {
|
|
60
|
+
const tr = discoverCommandLine(userEmail, surface);
|
|
55
61
|
try {
|
|
56
62
|
(0, child_process_1.execSync)(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: 'ignore' });
|
|
57
63
|
}
|
|
58
64
|
catch {
|
|
59
65
|
// task may not exist
|
|
60
66
|
}
|
|
61
|
-
|
|
67
|
+
const schedule = trigger === 'logon'
|
|
68
|
+
? '/SC ONLOGON'
|
|
69
|
+
: `/SC DAILY /ST ${String(hour).padStart(2, '0')}:00`;
|
|
70
|
+
try {
|
|
71
|
+
(0, child_process_1.execSync)(`schtasks /Create /F /TN "${TASK_NAME}" ${schedule} /RL LIMITED /TR "${tr.replace(/"/g, '\\"')}"`, { stdio: 'inherit' });
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (trigger !== 'logon')
|
|
75
|
+
throw error;
|
|
76
|
+
const launcher = windowsStartupLauncherPath();
|
|
77
|
+
fs.mkdirSync(path.dirname(launcher), { recursive: true });
|
|
78
|
+
fs.writeFileSync(launcher, `@echo off\r\n${tr} > "%USERPROFILE%\\.fullcourtdefense-discover.log" 2>&1\r\n`, 'utf8');
|
|
79
|
+
console.log(`Task Scheduler denied access; installed user logon launcher instead: ${launcher}`);
|
|
80
|
+
}
|
|
62
81
|
}
|
|
63
|
-
function installMacSchedule(hour, userEmail) {
|
|
82
|
+
function installMacSchedule(hour, userEmail, surface, trigger = 'daily') {
|
|
64
83
|
const label = 'ai.fullcourtdefense.discover';
|
|
65
84
|
const plistDir = path.join(os.homedir(), 'Library', 'LaunchAgents');
|
|
66
85
|
const plistPath = path.join(plistDir, `${label}.plist`);
|
|
67
86
|
fs.mkdirSync(plistDir, { recursive: true });
|
|
68
|
-
const cmd = discoverCommandLine(userEmail).split(/\s+/);
|
|
87
|
+
const cmd = discoverCommandLine(userEmail, surface).split(/\s+/);
|
|
69
88
|
const program = cmd.shift() || process.execPath;
|
|
89
|
+
const triggerXml = trigger === 'logon'
|
|
90
|
+
? '<key>RunAtLoad</key><true/>'
|
|
91
|
+
: `<key>StartCalendarInterval</key>
|
|
92
|
+
<dict><key>Hour</key><integer>${hour}</integer><key>Minute</key><integer>0</integer></dict>`;
|
|
70
93
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
71
94
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
72
95
|
<plist version="1.0">
|
|
@@ -74,8 +97,7 @@ function installMacSchedule(hour, userEmail) {
|
|
|
74
97
|
<key>Label</key><string>${label}</string>
|
|
75
98
|
<key>ProgramArguments</key>
|
|
76
99
|
<array>${[program, ...cmd].map(part => `<string>${part.replace(/&/g, '&').replace(/</g, '<')}</string>`).join('')}</array>
|
|
77
|
-
|
|
78
|
-
<dict><key>Hour</key><integer>${hour}</integer><key>Minute</key><integer>0</integer></dict>
|
|
100
|
+
${triggerXml}
|
|
79
101
|
<key>StandardOutPath</key><string>${path.join(os.homedir(), '.fullcourtdefense-discover.log')}</string>
|
|
80
102
|
<key>StandardErrorPath</key><string>${path.join(os.homedir(), '.fullcourtdefense-discover.err.log')}</string>
|
|
81
103
|
</dict>
|
|
@@ -84,8 +106,9 @@ function installMacSchedule(hour, userEmail) {
|
|
|
84
106
|
(0, child_process_1.spawnSync)('launchctl', ['unload', plistPath], { stdio: 'ignore' });
|
|
85
107
|
(0, child_process_1.spawnSync)('launchctl', ['load', plistPath], { stdio: 'inherit' });
|
|
86
108
|
}
|
|
87
|
-
function installLinuxCron(hour, userEmail) {
|
|
88
|
-
const
|
|
109
|
+
function installLinuxCron(hour, userEmail, surface, trigger = 'daily') {
|
|
110
|
+
const schedule = trigger === 'logon' ? '@reboot' : `0 ${hour} * * *`;
|
|
111
|
+
const line = `${schedule} ${discoverCommandLine(userEmail, surface)} >> ${path.join(os.homedir(), '.fullcourtdefense-discover.log')} 2>&1`;
|
|
89
112
|
const marker = '# fullcourtdefense-discover';
|
|
90
113
|
let crontab = '';
|
|
91
114
|
try {
|
|
@@ -101,16 +124,30 @@ function installLinuxCron(hour, userEmail) {
|
|
|
101
124
|
}
|
|
102
125
|
function installDailyDiscoverSchedule(args = {}) {
|
|
103
126
|
const hour = Number.isFinite(args.hour) ? Math.min(23, Math.max(0, args.hour)) : 9;
|
|
127
|
+
const trigger = args.trigger || 'daily';
|
|
104
128
|
if (process.platform === 'win32')
|
|
105
|
-
installWindowsSchedule(hour, args.userEmail);
|
|
129
|
+
installWindowsSchedule(hour, args.userEmail, args.surface, trigger);
|
|
106
130
|
else if (process.platform === 'darwin')
|
|
107
|
-
installMacSchedule(hour, args.userEmail);
|
|
131
|
+
installMacSchedule(hour, args.userEmail, args.surface, trigger);
|
|
108
132
|
else
|
|
109
|
-
installLinuxCron(hour, args.userEmail);
|
|
133
|
+
installLinuxCron(hour, args.userEmail, args.surface, trigger);
|
|
110
134
|
}
|
|
111
135
|
function uninstallDailyDiscoverSchedule() {
|
|
112
136
|
if (process.platform === 'win32') {
|
|
113
|
-
|
|
137
|
+
try {
|
|
138
|
+
(0, child_process_1.execSync)(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: 'inherit' });
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Scheduled Task may not exist or may be inaccessible.
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const launcher = windowsStartupLauncherPath();
|
|
145
|
+
if (fs.existsSync(launcher))
|
|
146
|
+
fs.unlinkSync(launcher);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// ignore
|
|
150
|
+
}
|
|
114
151
|
return;
|
|
115
152
|
}
|
|
116
153
|
if (process.platform === 'darwin') {
|
package/dist/index.js
CHANGED
|
@@ -124,6 +124,7 @@ function printHelp() {
|
|
|
124
124
|
scan Runs the scan. Use --local for inside-organization scans.
|
|
125
125
|
discover Finds MCP servers, local secrets, agent rules/skills, and machine
|
|
126
126
|
blast radius on this laptop. Use --surface all --upload for AI Fleet.
|
|
127
|
+
Use --schedule logon to upload inventory/posture at machine login.
|
|
127
128
|
install-cursor-hook
|
|
128
129
|
Installs a Cursor hook so EVERY agent action on this machine is
|
|
129
130
|
checked against your org's Action Policies — in any repo/folder.
|
|
@@ -305,6 +306,7 @@ function printHelp() {
|
|
|
305
306
|
$ fullcourtdefense login --token <fleet-enrollment-token>
|
|
306
307
|
$ fullcourtdefense install-all
|
|
307
308
|
$ fullcourtdefense install-all --auto-protect true --upload
|
|
309
|
+
$ fullcourtdefense discover --surface all --upload --schedule logon
|
|
308
310
|
$ fullcourtdefense install-mcp-gateway --clients cursor,codex --mcp-command npm --mcp-args "run mcp"
|
|
309
311
|
$ fullcourtdefense install-codex-mcp-gateway --mcp-command npm --mcp-args "run mcp"
|
|
310
312
|
$ fullcourtdefense scan --system-prompt ./prompts/system.md --fail-threshold 80
|
package/dist/version.json
CHANGED