@lifeaitools/rdc-skills 0.24.38 → 0.24.39
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/.claude/settings.json +15 -15
- package/.claude-plugin/marketplace.json +21 -21
- package/.claude-plugin/plugin.json +1371 -1371
- package/.github/workflows/publish.yml +34 -34
- package/.github/workflows/self-test.yml +58 -58
- package/CHANGELOG.md +310 -310
- package/LICENSE +21 -21
- package/MANIFEST.md +221 -221
- package/README.md +377 -377
- package/README.sandbox.md +3 -3
- package/assets/watcher/viewer.html +164 -164
- package/bin/rdc-skills-mcp.mjs +316 -316
- package/commands/build.md +183 -183
- package/commands/collab.md +180 -180
- package/commands/deploy.md +152 -152
- package/commands/design.md +31 -31
- package/commands/edit.md +28 -28
- package/commands/fixit.md +124 -124
- package/commands/handoff.md +173 -173
- package/commands/help.md +95 -95
- package/commands/overnight.md +220 -220
- package/commands/plan.md +158 -158
- package/commands/preplan.md +131 -131
- package/commands/prototype.md +145 -145
- package/commands/release.md +49 -49
- package/commands/report.md +99 -99
- package/commands/review.md +120 -120
- package/commands/self-test.md +113 -113
- package/commands/status.md +86 -86
- package/commands/watch.md +98 -98
- package/commands/workitems.md +137 -137
- package/git-sha.json +1 -1
- package/guides/agent-bootstrap.md +295 -295
- package/guides/agents/backend.md +104 -104
- package/guides/agents/content.md +94 -94
- package/guides/agents/cs2.md +56 -56
- package/guides/agents/data.md +87 -87
- package/guides/agents/design.md +77 -77
- package/guides/agents/frontend.md +92 -92
- package/guides/agents/infrastructure.md +81 -81
- package/guides/agents/setup.md +281 -281
- package/guides/agents/verify.md +151 -151
- package/guides/agents/viz.md +106 -106
- package/guides/backend.md +146 -146
- package/guides/content.md +147 -147
- package/guides/cs2.md +190 -190
- package/guides/data.md +123 -123
- package/guides/design.md +116 -116
- package/guides/engineering-behavior.md +43 -43
- package/guides/escalation-protocol.md +125 -125
- package/guides/frontend.md +151 -151
- package/guides/history-md-spec.md +297 -297
- package/guides/infrastructure.md +179 -179
- package/guides/lessons-learned-spec.md +153 -153
- package/guides/output-contract.md +108 -108
- package/guides/publish-md-spec.md +289 -289
- package/guides/rdc-skills-startup.md +30 -30
- package/guides/verify.md +11 -11
- package/hooks/check-cwd.js +31 -31
- package/hooks/check-rdc-environment.js +164 -164
- package/hooks/check-services.js +6 -6
- package/hooks/check-stale-work-items.js +19 -19
- package/hooks/foreground-process-gate.js +128 -128
- package/hooks/gate-watchdog-selfcheck.js +257 -257
- package/hooks/hook-logger.js +25 -25
- package/hooks/lib/run-evidence-gate.mjs +241 -241
- package/hooks/no-stop-open-epics.js +127 -127
- package/hooks/post-tool-batch-gate.js +203 -203
- package/hooks/post-work-check.js +21 -21
- package/hooks/postcompact-log.js +13 -13
- package/hooks/precompact-log.js +13 -13
- package/hooks/rate-limit-retry.js +46 -46
- package/hooks/rdc-invocation-marker.js +157 -157
- package/hooks/rdc-output-contract-gate.js +94 -94
- package/hooks/require-work-item-on-commit.js +294 -294
- package/hooks/restart-brief.js +19 -19
- package/hooks/run-hidden-hook.ps1 +47 -47
- package/hooks/task-completed-gate.js +274 -274
- package/hooks/work-item-exit-gate.js +944 -944
- package/lib/catalog.mjs +236 -236
- package/lib/cloud-rewrite.mjs +155 -155
- package/package.json +56 -56
- package/rules/work-items-rpc.md +520 -520
- package/scaffold/templates/HISTORY.md.template +39 -39
- package/scaffold/templates/PUBLISH.md.template +21 -21
- package/scaffold/templates/brochure-studio-default.html +70 -70
- package/scripts/acceptance.mjs +502 -502
- package/scripts/fixtures/guides/bad-guide.md +15 -15
- package/scripts/fixtures/guides-clean/good-guide.md +16 -16
- package/scripts/install-rdc-skills.js +1289 -1289
- package/scripts/install.ps1 +202 -202
- package/scripts/install.sh +132 -132
- package/scripts/lib/assertions.mjs +287 -287
- package/scripts/lib/manifest-schema.mjs +754 -754
- package/scripts/lib/runner.mjs +465 -465
- package/scripts/lib/sandbox.mjs +435 -435
- package/scripts/prepack.mjs +32 -32
- package/scripts/rdc-brochure.mjs +464 -464
- package/scripts/rdc-design-cli.mjs +134 -134
- package/scripts/rebuild-mcp.mjs +107 -107
- package/scripts/self-test.mjs +1460 -1460
- package/scripts/stamp-git-sha.mjs +29 -29
- package/scripts/test-guide-validator.mjs +196 -196
- package/scripts/test-rdc-hooks.mjs +145 -145
- package/scripts/uninstall.ps1 +77 -77
- package/scripts/uninstall.sh +69 -69
- package/scripts/update.ps1 +43 -43
- package/scripts/update.sh +43 -43
- package/scripts/validate-place-histories.js +461 -461
- package/scripts/validate-publish-manifests.js +424 -424
- package/scripts/watch-init.mjs +100 -100
- package/skills/brochure/SKILL.md +107 -107
- package/skills/build/SKILL.md +563 -563
- package/skills/channel-formatter/SKILL.md +533 -533
- package/skills/co-develop/SKILL.md +196 -196
- package/skills/collab/SKILL.md +239 -239
- package/skills/convert/SKILL.md +140 -140
- package/skills/deploy/SKILL.md +541 -541
- package/skills/design/SKILL.md +211 -211
- package/skills/design/reference/ownership.md +16 -16
- package/skills/design/reference/rampa.md +92 -92
- package/skills/design/reference/studio-model.md +153 -153
- package/skills/edit/SKILL.md +98 -98
- package/skills/fixit/SKILL.md +165 -165
- package/skills/fs-mcp/SKILL.md +148 -148
- package/skills/handoff/SKILL.md +236 -200
- package/skills/help/SKILL.md +143 -143
- package/skills/housekeeping/SKILL.md +189 -189
- package/skills/lifeai-brochure-author/SKILL.md +340 -340
- package/skills/overnight/SKILL.md +251 -251
- package/skills/plan/SKILL.md +345 -345
- package/skills/preplan/SKILL.md +90 -90
- package/skills/prototype/SKILL.md +150 -150
- package/skills/rdc-brochurify/SKILL.md +245 -245
- package/skills/rdc-extract-verifier-rules/SKILL.md +191 -191
- package/skills/release/SKILL.md +140 -140
- package/skills/report/SKILL.md +100 -100
- package/skills/review/SKILL.md +152 -152
- package/skills/rpms-filemap/SKILL.cloud.md +111 -111
- package/skills/rpms-filemap/SKILL.md +111 -111
- package/skills/self-test/SKILL.md +132 -132
- package/skills/status/SKILL.md +99 -99
- package/skills/terminal-config/SKILL.md +62 -62
- package/skills/tests/MATRIX.md +54 -54
- package/skills/tests/README.md +47 -47
- package/skills/tests/rdc-brochure.test.json +34 -34
- package/skills/tests/rdc-build.test.json +36 -36
- package/skills/tests/rdc-channel-formatter.test.json +45 -45
- package/skills/tests/rdc-co-develop.test.json +29 -29
- package/skills/tests/rdc-collab.test.json +29 -29
- package/skills/tests/rdc-convert.test.json +35 -35
- package/skills/tests/rdc-deploy.test.json +30 -30
- package/skills/tests/rdc-design.test.json +27 -27
- package/skills/tests/rdc-edit.test.json +29 -29
- package/skills/tests/rdc-fixit.test.json +36 -36
- package/skills/tests/rdc-fs-mcp.test.json +36 -36
- package/skills/tests/rdc-handoff.test.json +28 -28
- package/skills/tests/rdc-help.test.json +29 -29
- package/skills/tests/rdc-housekeeping.test.json +31 -31
- package/skills/tests/rdc-lifeai-brochure-author.test.json +35 -35
- package/skills/tests/rdc-overnight.test.json +37 -37
- package/skills/tests/rdc-plan.test.json +27 -27
- package/skills/tests/rdc-preplan.test.json +31 -31
- package/skills/tests/rdc-prototype.test.json +28 -28
- package/skills/tests/rdc-rdc-brochurify.test.json +23 -23
- package/skills/tests/rdc-rdc-extract-verifier-rules.test.json +34 -34
- package/skills/tests/rdc-release.test.json +29 -29
- package/skills/tests/rdc-report.test.json +28 -28
- package/skills/tests/rdc-review.test.json +29 -29
- package/skills/tests/rdc-rpms-filemap.test.json +28 -28
- package/skills/tests/rdc-self-test.test.json +24 -24
- package/skills/tests/rdc-status.test.json +29 -29
- package/skills/tests/rdc-terminal-config.test.json +29 -29
- package/skills/tests/rdc-watch.test.json +24 -24
- package/skills/tests/rdc-workitems.test.json +27 -27
- package/skills/watch/SKILL.md +97 -97
- package/skills/workitems/SKILL.md +151 -151
- package/tests/acceptance.test.mjs +59 -59
- package/tests/channel-formatter.contract.test.mjs +251 -251
- package/tests/curl-surface.test.mjs +289 -289
- package/tests/harness-gates.test.mjs +325 -325
- package/tests/help-surface.test.mjs +61 -61
- package/tests/install-rdc-skills.test.mjs +49 -49
- package/tests/manifest-contract-fields.test.mjs +78 -78
- package/tests/mcp.test.mjs +271 -271
- package/tests/require-work-item-on-commit.test.mjs +162 -162
- package/tests/run-evidence-gate.test.mjs +82 -82
- package/tests/skill-test-matrix.test.mjs +66 -66
- package/tests/validate-skills.js +27 -27
- package/tests/work-item-exit-gate-l2.test.mjs +368 -368
- package/tests/work-item-exit-gate-l3.test.mjs +197 -197
|
@@ -1,128 +1,128 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* PreToolUse hook — block focus-stealing foreground process launches.
|
|
4
|
-
*/
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const hookLog = require('./hook-logger');
|
|
8
|
-
|
|
9
|
-
function readStdin() {
|
|
10
|
-
return new Promise((resolve) => {
|
|
11
|
-
let input = '';
|
|
12
|
-
process.stdin.setEncoding('utf8');
|
|
13
|
-
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
14
|
-
process.stdin.on('end', () => resolve(input));
|
|
15
|
-
process.stdin.resume();
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function block(message, details = {}) {
|
|
20
|
-
hookLog('foreground-process-gate', 'PreToolUse', 'block', details);
|
|
21
|
-
process.stdout.write(JSON.stringify({
|
|
22
|
-
systemMessage: `HARD BLOCK — Foreground process launch rejected.\n\n${message}`,
|
|
23
|
-
}));
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function pass(details = {}) {
|
|
28
|
-
hookLog('foreground-process-gate', 'PreToolUse', 'pass', details);
|
|
29
|
-
process.exit(0);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function toolText(raw) {
|
|
33
|
-
if (typeof raw.tool_input?.command === 'string') return raw.tool_input.command;
|
|
34
|
-
if (typeof raw.tool_input === 'string') return raw.tool_input;
|
|
35
|
-
try { return JSON.stringify(raw.tool_input || raw); } catch { return ''; }
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function hasHiddenIntent(command) {
|
|
39
|
-
return /-WindowStyle\s+Hidden/i.test(command) ||
|
|
40
|
-
/-WindowStyle\s+Minimized/i.test(command) ||
|
|
41
|
-
/windowsHide\s*:\s*true/i.test(command) ||
|
|
42
|
-
/CreateNoWindow\s*=\s*\$?true/i.test(command) ||
|
|
43
|
-
/Start-Job\b/i.test(command) ||
|
|
44
|
-
/--background\b/i.test(command) ||
|
|
45
|
-
/\bHEADLESS\s*=\s*(1|true)\b/i.test(command) ||
|
|
46
|
-
/\bCI\s*=\s*(1|true)\b/i.test(command);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function hasExplicitWindowOverride(command) {
|
|
50
|
-
return /\bRDC_ALLOW_WINDOW_FOCUS\s*=\s*(1|true)\b/i.test(command) ||
|
|
51
|
-
/\bRDC_INTERACTIVE_WINDOW\s*=\s*(1|true)\b/i.test(command);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function checkWindowFocusApi(command) {
|
|
55
|
-
if (hasExplicitWindowOverride(command)) return;
|
|
56
|
-
const focusApi = /\b(SetForegroundWindow|SwitchToThisWindow|AppActivate|SetWindowPos|ShowWindowAsync?|BringWindowToTop)\b/i;
|
|
57
|
-
const broadWindowApi = /\b(EnumWindows|Get-Process\s+\|\s*Where-Object|GetWindow|FindWindow)\b/i;
|
|
58
|
-
const windowMutation = /\b(minimi[sz]e|restore|foreground|focus|activate|collapse)\b/i;
|
|
59
|
-
if (focusApi.test(command) || (broadWindowApi.test(command) && windowMutation.test(command))) {
|
|
60
|
-
block(
|
|
61
|
-
'Window focus/restore/minimize/collapse operations are not allowed in agent-launched commands. Spawn helpers hidden/no-window instead; set RDC_ALLOW_WINDOW_FOCUS=1 only for an explicitly requested interactive recovery action.',
|
|
62
|
-
{ kind: 'window-focus-api' },
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function checkPlaywright(command) {
|
|
68
|
-
if (!/\b(playwright|@playwright\/test)\b/i.test(command)) return;
|
|
69
|
-
|
|
70
|
-
if (/\bplaywright\s+(show-report|codegen|open)\b/i.test(command)) {
|
|
71
|
-
block(
|
|
72
|
-
'Playwright report/codegen/open launches foreground UI. Use trace/report files as artifacts, or run a hidden/background smoke wrapper.',
|
|
73
|
-
{ kind: 'playwright-ui' },
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (/(^|[\s;&|])(--headed|--ui|PWDEBUG\s*=\s*1|PWDEBUG\s*=\s*true)(?=$|[\s;&|])/i.test(command)) {
|
|
78
|
-
block(
|
|
79
|
-
'Playwright must run headless in agent sessions. Remove `--headed`, `--ui`, and `PWDEBUG=1`; use `--reporter=list` or an artifact trace instead.',
|
|
80
|
-
{ kind: 'playwright-headed' },
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function checkPowerShell(command) {
|
|
86
|
-
if (!/\bStart-Process\b/i.test(command)) return;
|
|
87
|
-
if (hasHiddenIntent(command)) return;
|
|
88
|
-
block(
|
|
89
|
-
'`Start-Process` must include `-WindowStyle Hidden` or `-WindowStyle Minimized` for agent-launched node/cmd/ps1/test processes. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
|
|
90
|
-
{ kind: 'start-process' },
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function checkCmdStart(command) {
|
|
95
|
-
if (!/\bcmd(?:\.exe)?\s+\/c\s+start\b/i.test(command)) return;
|
|
96
|
-
if (/\bcmd(?:\.exe)?\s+\/c\s+start\s+(""|''|`"")?\s*\/b\b/i.test(command)) return;
|
|
97
|
-
block(
|
|
98
|
-
'`cmd /c start` must use `/min` or `/b` for background tools. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
|
|
99
|
-
{ kind: 'cmd-start' },
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function checkDirectShellLaunch(command) {
|
|
104
|
-
if (hasHiddenIntent(command)) return;
|
|
105
|
-
if (/\bpowershell(?:\.exe)?\b[^|\n]*(?:-File\s+[^|\n]*\.ps1|\.ps1\b)/i.test(command)) {
|
|
106
|
-
block(
|
|
107
|
-
'PowerShell script launches from agent tooling must use `-WindowStyle Hidden -NonInteractive` or a hidden wrapper.',
|
|
108
|
-
{ kind: 'powershell-ps1' },
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function main() {
|
|
114
|
-
let raw;
|
|
115
|
-
try { raw = JSON.parse(await readStdin()); } catch { process.exit(0); }
|
|
116
|
-
const command = toolText(raw);
|
|
117
|
-
if (!command) pass({ reason: 'no-command' });
|
|
118
|
-
|
|
119
|
-
checkWindowFocusApi(command);
|
|
120
|
-
checkPlaywright(command);
|
|
121
|
-
checkPowerShell(command);
|
|
122
|
-
checkCmdStart(command);
|
|
123
|
-
checkDirectShellLaunch(command);
|
|
124
|
-
|
|
125
|
-
pass({ reason: 'clean' });
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
main().catch((e) => block(`Foreground process gate crashed: ${e.message}`));
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* PreToolUse hook — block focus-stealing foreground process launches.
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const hookLog = require('./hook-logger');
|
|
8
|
+
|
|
9
|
+
function readStdin() {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
let input = '';
|
|
12
|
+
process.stdin.setEncoding('utf8');
|
|
13
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
14
|
+
process.stdin.on('end', () => resolve(input));
|
|
15
|
+
process.stdin.resume();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function block(message, details = {}) {
|
|
20
|
+
hookLog('foreground-process-gate', 'PreToolUse', 'block', details);
|
|
21
|
+
process.stdout.write(JSON.stringify({
|
|
22
|
+
systemMessage: `HARD BLOCK — Foreground process launch rejected.\n\n${message}`,
|
|
23
|
+
}));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function pass(details = {}) {
|
|
28
|
+
hookLog('foreground-process-gate', 'PreToolUse', 'pass', details);
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function toolText(raw) {
|
|
33
|
+
if (typeof raw.tool_input?.command === 'string') return raw.tool_input.command;
|
|
34
|
+
if (typeof raw.tool_input === 'string') return raw.tool_input;
|
|
35
|
+
try { return JSON.stringify(raw.tool_input || raw); } catch { return ''; }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function hasHiddenIntent(command) {
|
|
39
|
+
return /-WindowStyle\s+Hidden/i.test(command) ||
|
|
40
|
+
/-WindowStyle\s+Minimized/i.test(command) ||
|
|
41
|
+
/windowsHide\s*:\s*true/i.test(command) ||
|
|
42
|
+
/CreateNoWindow\s*=\s*\$?true/i.test(command) ||
|
|
43
|
+
/Start-Job\b/i.test(command) ||
|
|
44
|
+
/--background\b/i.test(command) ||
|
|
45
|
+
/\bHEADLESS\s*=\s*(1|true)\b/i.test(command) ||
|
|
46
|
+
/\bCI\s*=\s*(1|true)\b/i.test(command);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hasExplicitWindowOverride(command) {
|
|
50
|
+
return /\bRDC_ALLOW_WINDOW_FOCUS\s*=\s*(1|true)\b/i.test(command) ||
|
|
51
|
+
/\bRDC_INTERACTIVE_WINDOW\s*=\s*(1|true)\b/i.test(command);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function checkWindowFocusApi(command) {
|
|
55
|
+
if (hasExplicitWindowOverride(command)) return;
|
|
56
|
+
const focusApi = /\b(SetForegroundWindow|SwitchToThisWindow|AppActivate|SetWindowPos|ShowWindowAsync?|BringWindowToTop)\b/i;
|
|
57
|
+
const broadWindowApi = /\b(EnumWindows|Get-Process\s+\|\s*Where-Object|GetWindow|FindWindow)\b/i;
|
|
58
|
+
const windowMutation = /\b(minimi[sz]e|restore|foreground|focus|activate|collapse)\b/i;
|
|
59
|
+
if (focusApi.test(command) || (broadWindowApi.test(command) && windowMutation.test(command))) {
|
|
60
|
+
block(
|
|
61
|
+
'Window focus/restore/minimize/collapse operations are not allowed in agent-launched commands. Spawn helpers hidden/no-window instead; set RDC_ALLOW_WINDOW_FOCUS=1 only for an explicitly requested interactive recovery action.',
|
|
62
|
+
{ kind: 'window-focus-api' },
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function checkPlaywright(command) {
|
|
68
|
+
if (!/\b(playwright|@playwright\/test)\b/i.test(command)) return;
|
|
69
|
+
|
|
70
|
+
if (/\bplaywright\s+(show-report|codegen|open)\b/i.test(command)) {
|
|
71
|
+
block(
|
|
72
|
+
'Playwright report/codegen/open launches foreground UI. Use trace/report files as artifacts, or run a hidden/background smoke wrapper.',
|
|
73
|
+
{ kind: 'playwright-ui' },
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (/(^|[\s;&|])(--headed|--ui|PWDEBUG\s*=\s*1|PWDEBUG\s*=\s*true)(?=$|[\s;&|])/i.test(command)) {
|
|
78
|
+
block(
|
|
79
|
+
'Playwright must run headless in agent sessions. Remove `--headed`, `--ui`, and `PWDEBUG=1`; use `--reporter=list` or an artifact trace instead.',
|
|
80
|
+
{ kind: 'playwright-headed' },
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function checkPowerShell(command) {
|
|
86
|
+
if (!/\bStart-Process\b/i.test(command)) return;
|
|
87
|
+
if (hasHiddenIntent(command)) return;
|
|
88
|
+
block(
|
|
89
|
+
'`Start-Process` must include `-WindowStyle Hidden` or `-WindowStyle Minimized` for agent-launched node/cmd/ps1/test processes. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
|
|
90
|
+
{ kind: 'start-process' },
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function checkCmdStart(command) {
|
|
95
|
+
if (!/\bcmd(?:\.exe)?\s+\/c\s+start\b/i.test(command)) return;
|
|
96
|
+
if (/\bcmd(?:\.exe)?\s+\/c\s+start\s+(""|''|`"")?\s*\/b\b/i.test(command)) return;
|
|
97
|
+
block(
|
|
98
|
+
'`cmd /c start` must use `/min` or `/b` for background tools. Focus/restore/collapse APIs remain blocked unless explicitly requested.',
|
|
99
|
+
{ kind: 'cmd-start' },
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function checkDirectShellLaunch(command) {
|
|
104
|
+
if (hasHiddenIntent(command)) return;
|
|
105
|
+
if (/\bpowershell(?:\.exe)?\b[^|\n]*(?:-File\s+[^|\n]*\.ps1|\.ps1\b)/i.test(command)) {
|
|
106
|
+
block(
|
|
107
|
+
'PowerShell script launches from agent tooling must use `-WindowStyle Hidden -NonInteractive` or a hidden wrapper.',
|
|
108
|
+
{ kind: 'powershell-ps1' },
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function main() {
|
|
114
|
+
let raw;
|
|
115
|
+
try { raw = JSON.parse(await readStdin()); } catch { process.exit(0); }
|
|
116
|
+
const command = toolText(raw);
|
|
117
|
+
if (!command) pass({ reason: 'no-command' });
|
|
118
|
+
|
|
119
|
+
checkWindowFocusApi(command);
|
|
120
|
+
checkPlaywright(command);
|
|
121
|
+
checkPowerShell(command);
|
|
122
|
+
checkCmdStart(command);
|
|
123
|
+
checkDirectShellLaunch(command);
|
|
124
|
+
|
|
125
|
+
pass({ reason: 'clean' });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
main().catch((e) => block(`Foreground process gate crashed: ${e.message}`));
|