requestshield 0.1.4 → 0.1.6

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.
Files changed (37) hide show
  1. package/README.md +421 -85
  2. package/config/.env.prod +7 -0
  3. package/package.json +21 -12
  4. package/skills/requestshield/SKILL.md +299 -307
  5. package/skills/requestshield/assets/AGENTS.codex.md +62 -62
  6. package/skills/requestshield/references/backend-java-core.md +128 -128
  7. package/skills/requestshield/references/backend-spring-boot.md +145 -145
  8. package/skills/requestshield/references/browser-manual.md +210 -210
  9. package/skills/requestshield/references/browser-seamless.md +156 -164
  10. package/skills/requestshield/references/cli.md +107 -182
  11. package/skills/requestshield/references/integration-planning.md +362 -389
  12. package/skills/requestshield/references/troubleshooting.md +114 -118
  13. package/src/agent-detector.mjs +102 -74
  14. package/src/api-client.mjs +115 -79
  15. package/src/args.mjs +140 -80
  16. package/src/browser-opener.mjs +32 -0
  17. package/src/cli.mjs +277 -51
  18. package/src/commands/agent-setup.mjs +182 -185
  19. package/src/commands/application-mutations.mjs +33 -0
  20. package/src/commands/application-response.mjs +55 -0
  21. package/src/commands/apps-get.mjs +20 -0
  22. package/src/commands/apps-list.mjs +94 -0
  23. package/src/commands/auth-status.mjs +37 -0
  24. package/src/commands/keys-create.mjs +7 -38
  25. package/src/commands/mutation-support.mjs +110 -0
  26. package/src/commands/secret-commands.mjs +45 -0
  27. package/src/commands/signin.mjs +70 -57
  28. package/src/commands/signout.mjs +9 -0
  29. package/src/commands/update-check.mjs +12 -4
  30. package/src/config.mjs +150 -0
  31. package/src/entrypoint.mjs +24 -0
  32. package/src/errors.mjs +3 -1
  33. package/src/main.mjs +5 -24
  34. package/src/oauth-client.mjs +153 -0
  35. package/src/oauth-loopback.mjs +120 -0
  36. package/src/session-files.mjs +213 -0
  37. package/src/session-store.mjs +177 -64
package/src/cli.mjs CHANGED
@@ -1,51 +1,277 @@
1
- #!/usr/bin/env node
2
- // @ts-check
3
-
4
- import { parseArgs } from "./args.mjs";
5
- import { ManagementApiClient } from "./api-client.mjs";
6
- import { SessionStore } from "./session-store.mjs";
7
- import { signin } from "./commands/signin.mjs";
8
- import { createKeys } from "./commands/keys-create.mjs";
9
- import { setupAgent } from "./commands/agent-setup.mjs";
10
- import { checkForUpdate } from "./commands/update-check.mjs";
11
- import packageJson from "../package.json" with { type: "json" };
12
-
13
- /**
14
- * @param {string[]} argv
15
- * @param {{ log?: (message: string) => void, api?: ManagementApiClient, sessions?: SessionStore, env?: NodeJS.ProcessEnv, homeDir?: string, sourceDir?: string, executablePath?: string, detectAgents?: () => Promise<Array<"codex" | "claude">>, selectAgent?: (detected: Array<"codex" | "claude">) => Promise<"codex" | "claude">, wait?: (milliseconds: number) => Promise<unknown>, confirm?: () => Promise<boolean>, fetchImpl?: typeof fetch, confirmUpdate?: () => Promise<boolean>, installLatest?: (packageName: string, version: string) => Promise<void> }} [deps]
16
- */
17
- export async function run(argv, deps = {}) {
18
- const parsed = parseArgs(argv);
19
- const log = deps.log ?? ((message) => console.log(message));
20
- if (parsed.command === "help") return log(parsed.help);
21
- if (parsed.command === "version") return log("requestshield " + packageJson.version);
22
- if (parsed.command === "update-check") {
23
- return checkForUpdate({
24
- currentVersion: packageJson.version,
25
- packageName: packageJson.name,
26
- log,
27
- fetchImpl: deps.fetchImpl,
28
- confirm: deps.confirmUpdate,
29
- install: deps.installLatest,
30
- });
31
- }
32
-
33
- if (parsed.command === "agent-setup") {
34
- return setupAgent(parsed, { log, ...deps });
35
- }
36
-
37
- const env = deps.env ?? process.env;
38
-
39
- const api = deps.api ?? new ManagementApiClient({
40
- baseUrl:
41
- env.REQUESTSHIELD_API_URL ??
42
- "https://api.intellifend.ai",
43
- });
44
-
45
- const sessions = deps.sessions ?? new SessionStore({
46
- env,
47
- homeDir: deps.homeDir,
48
- });
49
- if (parsed.command === "signin") return signin({ api, sessions, log, ...deps });
50
- if (parsed.command === "keys-create") return createKeys(parsed, { api, sessions, log, ...deps });
51
- }
1
+ #!/usr/bin/env node
2
+ // @ts-check
3
+
4
+ import { parseArgs } from "./args.mjs";
5
+ import { ManagementApiClient } from "./api-client.mjs";
6
+ import { SessionStore } from "./session-store.mjs";
7
+ import { OAuthClient } from "./oauth-client.mjs";
8
+
9
+ import { signin } from "./commands/signin.mjs";
10
+ import { createKeys } from "./commands/keys-create.mjs";
11
+ import { renameApp, setAppEnabled } from "./commands/application-mutations.mjs";
12
+ import { rotateSecret, revealSecret, revokeSecret } from "./commands/secret-commands.mjs";
13
+ import { showAuthStatus } from "./commands/auth-status.mjs";
14
+ import { signout } from "./commands/signout.mjs";
15
+ import { listApps } from "./commands/apps-list.mjs";
16
+ import { getApp } from "./commands/apps-get.mjs";
17
+ import { setupAgent } from "./commands/agent-setup.mjs";
18
+ import { checkForUpdate } from "./commands/update-check.mjs";
19
+
20
+ import packageJson from "../package.json" with { type: "json" };
21
+ import { getApiUrl, getAuthorizationIssuer, getCommandInvocation, getCommandName, getOAuthConfig } from "./config.mjs";
22
+
23
+ /**
24
+ * @typedef {{
25
+ * log: (message: string) => void,
26
+ * warn?: (message: string) => void,
27
+ * api?: ManagementApiClient,
28
+ * sessions?: SessionStore,
29
+ * oauth?: OAuthClient,
30
+ * authorizationIssuer?: string,
31
+ * openBrowser?: typeof import('./browser-opener.mjs').openBrowser,
32
+ * signal?: AbortSignal,
33
+ * env?: NodeJS.ProcessEnv,
34
+ * profile?: import('./config.mjs').Profile,
35
+ * homeDir?: string,
36
+ * sourceDir?: string,
37
+ * executablePath?: string,
38
+ * detectAgents?: () => Promise<Array<"codex" | "claude">>,
39
+ * selectAgent?: (
40
+ * detected: Array<"codex" | "claude">
41
+ * ) => Promise<"codex" | "claude">,
42
+ * wait?: (milliseconds: number) => Promise<unknown>,
43
+ * confirm?: () => Promise<boolean>,
44
+ * fetchImpl?: typeof fetch,
45
+ * confirmUpdate?: () => Promise<boolean>,
46
+ * installLatest?: (
47
+ * packageName: string,
48
+ * version: string
49
+ * ) => Promise<void>
50
+ * }} CommandContext
51
+ */
52
+
53
+ /**
54
+ * @typedef {CommandContext & {
55
+ * api: ManagementApiClient,
56
+ * sessions: SessionStore
57
+ * }} AuthenticatedCommandContext
58
+ */
59
+
60
+ /**
61
+ * @typedef {{
62
+ * requiresApiSession: boolean,
63
+ * handler: (
64
+ * parsed: any,
65
+ * context: CommandContext
66
+ * ) => unknown | Promise<unknown>
67
+ * }} CommandHandler
68
+ */
69
+
70
+ /**
71
+ * Put every CLI command handler here.
72
+ *
73
+ * @type {Record<string, CommandHandler>}
74
+ */
75
+ const COMMAND_HANDLERS = {
76
+ "help": {
77
+ requiresApiSession: false,
78
+ handler: (parsed, context) =>
79
+ context.log(parsed.help.replace(/^ requestshield /gm, ` ${getCommandInvocation(context.profile)} `)),
80
+ },
81
+
82
+ "version": {
83
+ requiresApiSession: false,
84
+ handler: (_parsed, context) =>
85
+ context.log(`${getCommandName(context.profile)} ${packageJson.version}`),
86
+ },
87
+
88
+ "update-check": {
89
+ requiresApiSession: false,
90
+ handler: (_parsed, context) =>
91
+ checkForUpdate({
92
+ profile: context.profile,
93
+ currentVersion: packageJson.version,
94
+ packageName: packageJson.name,
95
+ log: context.log,
96
+ fetchImpl: context.fetchImpl,
97
+ confirm: context.confirmUpdate,
98
+ install: context.installLatest,
99
+ }),
100
+ },
101
+
102
+ "agent-setup": {
103
+ requiresApiSession: false,
104
+ handler: (parsed, context) =>
105
+ setupAgent(parsed, context),
106
+ },
107
+
108
+ "signin": {
109
+ requiresApiSession: false,
110
+ handler: (parsed, context) => {
111
+ const env = context.env ?? process.env;
112
+ const oauth = context.oauth ?? new OAuthClient({config: getOAuthConfig(context.profile), fetchImpl: context.fetchImpl});
113
+ const authorizationIssuer = context.authorizationIssuer ?? (context.oauth
114
+ ? oauth.config.issuer : getAuthorizationIssuer(context.profile, oauth.config.issuer));
115
+ const sessions = context.sessions ?? new SessionStore({env, homeDir: context.homeDir, oauth, config: oauth.config, profile: context.profile});
116
+ return signin(parsed, {...context, oauth, sessions, authorizationIssuer});
117
+ },
118
+ },
119
+
120
+ "keys-create": {
121
+ requiresApiSession: true,
122
+ handler: (parsed, context) =>
123
+ createKeys(parsed, requireApiSession(context)),
124
+ },
125
+
126
+ "keys-rotate": {requiresApiSession: true, handler: (parsed, context) => rotateSecret(parsed, requireApiSession(context))},
127
+ "keys-reveal": {requiresApiSession: true, handler: (parsed, context) => revealSecret(parsed, requireApiSession(context))},
128
+ "keys-revoke": {requiresApiSession: true, handler: (parsed, context) => revokeSecret(parsed, requireApiSession(context))},
129
+ "apps-rename": {requiresApiSession: true, handler: (parsed, context) => renameApp(parsed, requireApiSession(context))},
130
+ "apps-enable": {requiresApiSession: true, handler: (parsed, context) => setAppEnabled(parsed, requireApiSession(context))},
131
+ "apps-disable": {requiresApiSession: true, handler: (parsed, context) => setAppEnabled(parsed, requireApiSession(context))},
132
+ "auth-status": {requiresApiSession: false, handler: (parsed, context) => showAuthStatus(parsed, {...context, sessions: localSessions(context)})},
133
+ "signout": {requiresApiSession: false, handler: (parsed, context) => signout(parsed, {...context, sessions: localSessions(context)})},
134
+
135
+ "apps-list": {
136
+ requiresApiSession: true,
137
+ handler: (parsed, context) =>
138
+ listApps(parsed, requireApiSession(context)),
139
+ },
140
+
141
+ "apps-get": {
142
+ requiresApiSession: true,
143
+ handler: (parsed, context) =>
144
+ getApp(parsed, requireApiSession(context)),
145
+ },
146
+
147
+ };
148
+
149
+ /** @param {CommandContext} context */
150
+ function localSessions(context) {
151
+ return context.sessions ?? new SessionStore({env: context.env, homeDir: context.homeDir, profile: context.profile});
152
+ }
153
+
154
+ /**
155
+ * Narrow the shared context before an authenticated handler can use it.
156
+ *
157
+ * @param {CommandContext} context
158
+ * @returns {AuthenticatedCommandContext}
159
+ */
160
+ function requireApiSession(context) {
161
+ if (!context.api || !context.sessions) {
162
+ throw new Error("Authenticated command context was not initialized");
163
+ }
164
+
165
+ return {
166
+ ...context,
167
+ api: context.api,
168
+ sessions: context.sessions,
169
+ };
170
+ }
171
+
172
+ /**
173
+ * @param {string[]} argv
174
+ * @param {{
175
+ * log?: (message: string) => void,
176
+ * warn?: (message: string) => void,
177
+ * api?: ManagementApiClient,
178
+ * sessions?: SessionStore,
179
+ * oauth?: OAuthClient,
180
+ * authorizationIssuer?: string,
181
+ * openBrowser?: typeof import('./browser-opener.mjs').openBrowser,
182
+ * signal?: AbortSignal,
183
+ * env?: NodeJS.ProcessEnv,
184
+ * profile?: import('./config.mjs').Profile,
185
+ * homeDir?: string,
186
+ * sourceDir?: string,
187
+ * executablePath?: string,
188
+ * detectAgents?: () => Promise<Array<"codex" | "claude">>,
189
+ * selectAgent?: (
190
+ * detected: Array<"codex" | "claude">
191
+ * ) => Promise<"codex" | "claude">,
192
+ * wait?: (milliseconds: number) => Promise<unknown>,
193
+ * confirm?: () => Promise<boolean>,
194
+ * fetchImpl?: typeof fetch,
195
+ * confirmUpdate?: () => Promise<boolean>,
196
+ * installLatest?: (
197
+ * packageName: string,
198
+ * version: string
199
+ * ) => Promise<void>
200
+ * }} [deps]
201
+ */
202
+ export async function run(argv, deps = {}) {
203
+ const profile = deps.profile ?? "prod";
204
+ getCommandName(profile);
205
+ const parsed = parseArgs(argv);
206
+
207
+ const log =
208
+ deps.log ??
209
+ ((message) => console.log(message));
210
+
211
+ /*
212
+ * Find the requested command.
213
+ */
214
+ const command = COMMAND_HANDLERS[parsed.command];
215
+
216
+ if (!command) {
217
+ throw new Error(
218
+ `Unsupported command: ${String(parsed.command)}`
219
+ );
220
+ }
221
+
222
+ /*
223
+ * Dependencies available to every command.
224
+ */
225
+ /** @type {CommandContext} */
226
+ const context = {
227
+ ...deps,
228
+ profile,
229
+ log,
230
+ warn: deps.warn ?? ((message) => console.error(message)),
231
+ };
232
+
233
+ /*
234
+ * Only initialize the Management API and session
235
+ * for commands that require them.
236
+ */
237
+ if (command.requiresApiSession) {
238
+ const env =
239
+ deps.env ??
240
+ process.env;
241
+
242
+ const api =
243
+ deps.api ??
244
+ new ManagementApiClient({
245
+ baseUrl: getApiUrl(profile),
246
+ fetchImpl: deps.fetchImpl,
247
+ });
248
+
249
+ const sessions =
250
+ deps.sessions ??
251
+ new SessionStore({
252
+ env,
253
+ homeDir: deps.homeDir,
254
+ profile,
255
+ });
256
+
257
+ const authenticatedContext = {
258
+ ...context,
259
+ env,
260
+ api,
261
+ sessions,
262
+ };
263
+
264
+ return command.handler(
265
+ parsed,
266
+ authenticatedContext
267
+ );
268
+ }
269
+
270
+ /*
271
+ * Execute commands that do not need an API session.
272
+ */
273
+ return command.handler(
274
+ parsed,
275
+ context
276
+ );
277
+ }