@remotedraw/cli 0.2.0 → 0.2.2
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/README.md +20 -0
- package/dist/cli.d.ts +5 -37
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +197 -111
- package/dist/cloud.d.ts +1 -1
- package/dist/cloud.d.ts.map +1 -1
- package/dist/generated/agent-skill.d.ts +1 -1
- package/dist/generated/agent-skill.d.ts.map +1 -1
- package/dist/generated/agent-skill.js +1 -1
- package/dist/locales/en.d.ts +23 -14
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/en.js +23 -14
- package/dist/locales/index.d.ts +24 -15
- package/dist/locales/index.d.ts.map +1 -1
- package/dist/locales/nl.d.ts.map +1 -1
- package/dist/locales/nl.js +23 -14
- package/dist/scan.d.ts +58 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +544 -0
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -235,6 +235,24 @@ remotedraw agent --path .agents/skills/remotedraw --force
|
|
|
235
235
|
remotedraw agent --path .claude/skills/remotedraw --force
|
|
236
236
|
```
|
|
237
237
|
|
|
238
|
+
Before scaffolding into an existing app, read it first. `scan` names the web,
|
|
239
|
+
server, and iOS projects in a tree, where an `rd_sk_` key may live, any
|
|
240
|
+
RemoteDraw wiring already present, the integration options that fit, and the
|
|
241
|
+
product questions to settle with the user before building:
|
|
242
|
+
|
|
243
|
+
```sh
|
|
244
|
+
remotedraw scan --format json
|
|
245
|
+
remotedraw scan --path apps/customer-web
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
When the integration already has its files and only needs credentials,
|
|
249
|
+
provision without scaffolding (and without `--force`):
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
remotedraw project create --name "Field Notes" --env server # writes server/.env.local
|
|
253
|
+
remotedraw project create --name "Field Notes" --format json # prints the key once
|
|
254
|
+
```
|
|
255
|
+
|
|
238
256
|
## Command reference
|
|
239
257
|
|
|
240
258
|
```text
|
|
@@ -251,6 +269,8 @@ doctor Check project config, packages, and environment variables.
|
|
|
251
269
|
create-input Create or print a test input request payload.
|
|
252
270
|
examples List or install example projects.
|
|
253
271
|
agent Print or install the RemoteDraw agent skill.
|
|
272
|
+
scan Read a codebase and propose where RemoteDraw fits.
|
|
273
|
+
project Create a dashboard project and API key without scaffolding.
|
|
254
274
|
```
|
|
255
275
|
|
|
256
276
|
Run `remotedraw <command> --help` for command-specific options.
|
package/dist/cli.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type WizardDefinition, type WizardTerminal } from "./setup-wizard.js";
|
|
|
2
2
|
import { type CloudRuntime } from "./cloud.js";
|
|
3
3
|
import { type UpdateRuntime } from "./update.js";
|
|
4
4
|
export declare const CLI_VERSION: string;
|
|
5
|
-
export declare const REMOTEDRAW_SDK_RANGE = "^0.
|
|
5
|
+
export declare const REMOTEDRAW_SDK_RANGE = "^0.2.0";
|
|
6
6
|
export declare const REMOTEDRAW_CLI_RANGE = "^0.2.0";
|
|
7
7
|
export type CliResult = {
|
|
8
8
|
exitCode: number;
|
|
@@ -40,7 +40,7 @@ export type CliRuntime = CloudRuntime & UpdateRuntime & {
|
|
|
40
40
|
export declare const targetChoices: readonly ["web", "desktop", "ios", "headless"];
|
|
41
41
|
export declare const senderChoices: readonly ["remotedraw-ios", "embedded-web", "own-ios", "headless"];
|
|
42
42
|
export declare const sdkChoices: readonly ["react", "svelte", "js", "swift", "headless"];
|
|
43
|
-
declare const presetChoices: readonly ["
|
|
43
|
+
declare const presetChoices: readonly ["approval", "sketch", "photoMarkup", "pdfMarkup", "mapMarkup", "screenMarkup", "designReview", "pointer"];
|
|
44
44
|
declare const packageManagerChoices: readonly ["npm", "pnpm", "yarn", "bun"];
|
|
45
45
|
type TargetChoice = (typeof targetChoices)[number];
|
|
46
46
|
type SenderChoice = (typeof senderChoices)[number];
|
|
@@ -74,35 +74,12 @@ type PayloadOptions = {
|
|
|
74
74
|
export declare function createSessionPayload(options: PayloadOptions): {
|
|
75
75
|
expiresInMs?: number;
|
|
76
76
|
externalId: string;
|
|
77
|
-
markupPreset: "
|
|
77
|
+
markupPreset: "approval" | "sketch" | "photoMarkup" | "pdfMarkup" | "mapMarkup" | "screenMarkup" | "designReview" | "pointer";
|
|
78
78
|
target: {
|
|
79
|
+
kind: string;
|
|
80
|
+
label: string;
|
|
79
81
|
metadata: {
|
|
80
82
|
descriptor: {
|
|
81
|
-
version: number;
|
|
82
|
-
privacy: string;
|
|
83
|
-
surfaceRole: string;
|
|
84
|
-
inputIntent: "signature" | "initials";
|
|
85
|
-
label: string;
|
|
86
|
-
components: {
|
|
87
|
-
id: "signature" | "initials";
|
|
88
|
-
role: string;
|
|
89
|
-
inputIntent: "signature" | "initials";
|
|
90
|
-
required: boolean;
|
|
91
|
-
bounds: {
|
|
92
|
-
minX: number;
|
|
93
|
-
minY: number;
|
|
94
|
-
maxX: number;
|
|
95
|
-
maxY: number;
|
|
96
|
-
};
|
|
97
|
-
}[];
|
|
98
|
-
phoneHints: {
|
|
99
|
-
preferredLayout: string;
|
|
100
|
-
preferredTool: string;
|
|
101
|
-
primaryActionLabel: string;
|
|
102
|
-
showUndo: boolean;
|
|
103
|
-
showClear: boolean;
|
|
104
|
-
};
|
|
105
|
-
} | {
|
|
106
83
|
version: number;
|
|
107
84
|
privacy: string;
|
|
108
85
|
surfaceRole: string;
|
|
@@ -115,7 +92,6 @@ export declare function createSessionPayload(options: PayloadOptions): {
|
|
|
115
92
|
showUndo?: never;
|
|
116
93
|
showClear?: never;
|
|
117
94
|
};
|
|
118
|
-
components?: never;
|
|
119
95
|
} | {
|
|
120
96
|
version: number;
|
|
121
97
|
privacy: string;
|
|
@@ -129,16 +105,8 @@ export declare function createSessionPayload(options: PayloadOptions): {
|
|
|
129
105
|
showUndo: boolean;
|
|
130
106
|
showClear: boolean;
|
|
131
107
|
};
|
|
132
|
-
components?: never;
|
|
133
108
|
};
|
|
134
109
|
};
|
|
135
|
-
inputMapping?: "surface";
|
|
136
|
-
coordinateSpace?: {
|
|
137
|
-
width: number;
|
|
138
|
-
height: number;
|
|
139
|
-
};
|
|
140
|
-
kind: string;
|
|
141
|
-
label: string;
|
|
142
110
|
};
|
|
143
111
|
};
|
|
144
112
|
/**
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -5,9 +5,10 @@ import path from "node:path";
|
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { emitKeypressEvents } from "node:readline";
|
|
8
|
+
import { renderScanText, scanProject } from "./scan.js";
|
|
8
9
|
import { createInterface } from "node:readline/promises";
|
|
9
10
|
import { createWizardTerminal, runSetupWizard, } from "./setup-wizard.js";
|
|
10
|
-
import { assertEnvCanAcceptProvisioning, currentCliAccount, DEFAULT_REMOTEDRAW_API_BASE_URL, globalConfigPath, loginToRemoteDraw, logoutFromRemoteDraw, provisionRemoteDrawProject, readStoredLanguage, remoteDrawApiBaseUrl, writeStoredLanguage, writeProvisionedProjectSetup, } from "./cloud.js";
|
|
11
|
+
import { assertEnvCanAcceptProvisioning, currentCliAccount, DEFAULT_REMOTEDRAW_API_BASE_URL, globalConfigPath, loginToRemoteDraw, logoutFromRemoteDraw, provisionRemoteDrawProject, updateEnvContents, readStoredLanguage, remoteDrawApiBaseUrl, writeStoredLanguage, writeProvisionedProjectSetup, } from "./cloud.js";
|
|
11
12
|
import { LANGUAGE_ENV_VARS, SOURCE_LOCALE, extractLanguageFlag, languageChoices, languagePromptMessage, localeEndonym, normalizeLocale, resolveLocale, setActiveLocale, supportedLocaleList, SUPPORTED_LOCALES, systemLocaleHint, t, } from "./i18n.js";
|
|
12
13
|
import { CliError, cliError } from "./errors.js";
|
|
13
14
|
import { AGENT_SKILL_MARKDOWN } from "./generated/agent-skill.js";
|
|
@@ -23,7 +24,7 @@ export const CLI_VERSION = typeof packageMetadata.version === "string"
|
|
|
23
24
|
// private, and would silently accept a future breaking major once they were
|
|
24
25
|
// not. tests/generated-manifest.test.ts cross-checks every range below against
|
|
25
26
|
// the workspace manifests.
|
|
26
|
-
export const REMOTEDRAW_SDK_RANGE = "^0.
|
|
27
|
+
export const REMOTEDRAW_SDK_RANGE = "^0.2.0";
|
|
27
28
|
export const REMOTEDRAW_CLI_RANGE = "^0.2.0";
|
|
28
29
|
export const targetChoices = ["web", "desktop", "ios", "headless"];
|
|
29
30
|
export const senderChoices = [
|
|
@@ -40,8 +41,6 @@ export const sdkChoices = [
|
|
|
40
41
|
"headless",
|
|
41
42
|
];
|
|
42
43
|
const presetChoices = [
|
|
43
|
-
"signature",
|
|
44
|
-
"initials",
|
|
45
44
|
"approval",
|
|
46
45
|
"sketch",
|
|
47
46
|
"photoMarkup",
|
|
@@ -357,6 +356,10 @@ export async function runCli(args, runtime = createNodeRuntime()) {
|
|
|
357
356
|
return await examplesCommand(commandArgs, runtime);
|
|
358
357
|
case "agent":
|
|
359
358
|
return await agentCommand(commandArgs, runtime);
|
|
359
|
+
case "scan":
|
|
360
|
+
return await scanCommand(commandArgs, runtime);
|
|
361
|
+
case "project":
|
|
362
|
+
return await projectCommand(commandArgs, runtime);
|
|
360
363
|
default:
|
|
361
364
|
return requestedJsonOutput(args)
|
|
362
365
|
? jsonFailure(command, new Error(t("error.unknownCommand", { command })))
|
|
@@ -605,6 +608,8 @@ function mainHelpText() {
|
|
|
605
608
|
command("create-input", t("help.command.createInput")),
|
|
606
609
|
command("examples", t("help.command.examples")),
|
|
607
610
|
command("agent", t("help.command.agent")),
|
|
611
|
+
command("scan", t("help.command.scan")),
|
|
612
|
+
command("project", t("help.command.project")),
|
|
608
613
|
"",
|
|
609
614
|
t("help.startHere"),
|
|
610
615
|
" remotedraw guide",
|
|
@@ -641,13 +646,13 @@ function guideText() {
|
|
|
641
646
|
"",
|
|
642
647
|
t("guide.intro"),
|
|
643
648
|
t("guide.path.webIos"),
|
|
644
|
-
" remotedraw init --target web --sender remotedraw-ios --sdk react --preset
|
|
649
|
+
" remotedraw init --target web --sender remotedraw-ios --sdk react --preset sketch",
|
|
645
650
|
"",
|
|
646
651
|
t("guide.path.webOwned"),
|
|
647
652
|
" remotedraw init --target web --sender embedded-web --sdk react --preset sketch",
|
|
648
653
|
"",
|
|
649
654
|
t("guide.path.svelteIos"),
|
|
650
|
-
" remotedraw init --target web --sender remotedraw-ios --sdk svelte --preset
|
|
655
|
+
" remotedraw init --target web --sender remotedraw-ios --sdk svelte --preset sketch",
|
|
651
656
|
"",
|
|
652
657
|
t("guide.path.desktop"),
|
|
653
658
|
" remotedraw init --target desktop --sender remotedraw-ios --sdk js --preset sketch",
|
|
@@ -695,15 +700,33 @@ async function logoutCommand(args, runtime) {
|
|
|
695
700
|
}
|
|
696
701
|
async function whoamiCommand(args, runtime) {
|
|
697
702
|
const parsed = parseArgs(args, {
|
|
698
|
-
values: ["api-base-url"],
|
|
703
|
+
values: ["api-base-url", "format"],
|
|
699
704
|
booleans: ["help"],
|
|
700
705
|
});
|
|
701
706
|
if (parsed.booleans.has("help"))
|
|
702
707
|
return ok(whoamiHelpText());
|
|
708
|
+
const format = outputFormat(parsed);
|
|
703
709
|
const apiBaseUrl = remoteDrawApiBaseUrl(runtime.env, readString(parsed, "api-base-url"));
|
|
704
710
|
const account = await currentCliAccount(runtime, apiBaseUrl);
|
|
705
711
|
if (!account) {
|
|
706
|
-
|
|
712
|
+
const message = t("whoami.notLoggedIn", { url: apiBaseUrl });
|
|
713
|
+
return format === "json"
|
|
714
|
+
? jsonFailure("whoami", cliError("AUTH_REQUIRED", "whoami.notLoggedIn", { url: apiBaseUrl }))
|
|
715
|
+
: fail(message);
|
|
716
|
+
}
|
|
717
|
+
if (format === "json") {
|
|
718
|
+
return jsonResult({
|
|
719
|
+
ok: true,
|
|
720
|
+
command: "whoami",
|
|
721
|
+
apiBaseUrl,
|
|
722
|
+
account: {
|
|
723
|
+
userId: account.userId,
|
|
724
|
+
tenantId: account.tenantId,
|
|
725
|
+
tenantSlug: account.tenantSlug,
|
|
726
|
+
...(account.email ? { email: account.email } : {}),
|
|
727
|
+
...(account.name ? { name: account.name } : {}),
|
|
728
|
+
},
|
|
729
|
+
});
|
|
707
730
|
}
|
|
708
731
|
return ok([accountSummary(account), t("whoami.api", { url: apiBaseUrl })].join("\n"));
|
|
709
732
|
}
|
|
@@ -1154,7 +1177,7 @@ async function devCommand(args, runtime) {
|
|
|
1154
1177
|
t("dev.step1.detail"),
|
|
1155
1178
|
"",
|
|
1156
1179
|
t("dev.step2"),
|
|
1157
|
-
` remotedraw create-input --preset
|
|
1180
|
+
` remotedraw create-input --preset sketch --api-base-url ${apiBaseUrl}`,
|
|
1158
1181
|
"",
|
|
1159
1182
|
t("dev.step3"),
|
|
1160
1183
|
t("dev.step3.detail"),
|
|
@@ -1175,7 +1198,7 @@ async function createInputCommand(args, runtime) {
|
|
|
1175
1198
|
if (parsed.booleans.has("help"))
|
|
1176
1199
|
return ok(createInputHelpText());
|
|
1177
1200
|
const projectEnv = await environmentForProject(runtime.cwd, runtime);
|
|
1178
|
-
const preset = choice(readString(parsed, "preset") ?? "
|
|
1201
|
+
const preset = choice(readString(parsed, "preset") ?? "sketch", presetChoices, "preset");
|
|
1179
1202
|
const apiBaseUrl = readString(parsed, "api-base-url") ??
|
|
1180
1203
|
projectEnv.REMOTEDRAW_API_BASE_URL ??
|
|
1181
1204
|
DEFAULT_REMOTEDRAW_API_BASE_URL;
|
|
@@ -1255,6 +1278,125 @@ async function examplesCommand(args, runtime) {
|
|
|
1255
1278
|
});
|
|
1256
1279
|
return ok(scaffoldSummary(t("scaffold.verb.installedExample"), plan, outputDir, written, dryRun));
|
|
1257
1280
|
}
|
|
1281
|
+
async function projectCommand(args, runtime) {
|
|
1282
|
+
const parsed = parseArgs(args, {
|
|
1283
|
+
values: ["name", "key-name", "api-base-url", "env", "format"],
|
|
1284
|
+
booleans: ["help", "force"],
|
|
1285
|
+
});
|
|
1286
|
+
const subcommand = parsed.positionals[0];
|
|
1287
|
+
if (parsed.booleans.has("help") || subcommand == null) {
|
|
1288
|
+
return ok(projectHelpText());
|
|
1289
|
+
}
|
|
1290
|
+
if (subcommand !== "create") {
|
|
1291
|
+
throw cliError("INVALID_ARGUMENT", "project.error.unknownSubcommand", {
|
|
1292
|
+
subcommand,
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
const format = outputFormat(parsed);
|
|
1296
|
+
const name = readString(parsed, "name");
|
|
1297
|
+
if (name == null) {
|
|
1298
|
+
throw cliError("MISSING_ARGUMENT", "project.error.nameRequired");
|
|
1299
|
+
}
|
|
1300
|
+
const apiBaseUrl = readString(parsed, "api-base-url") ??
|
|
1301
|
+
runtime.env.REMOTEDRAW_API_BASE_URL ??
|
|
1302
|
+
DEFAULT_REMOTEDRAW_API_BASE_URL;
|
|
1303
|
+
const keyName = readString(parsed, "key-name");
|
|
1304
|
+
// Provisioning is separate from scaffolding on purpose: an integration that
|
|
1305
|
+
// already has its files must not have to --force-overwrite them to get a key.
|
|
1306
|
+
const provisioning = await provisionRemoteDrawProject(runtime, apiBaseUrl, {
|
|
1307
|
+
name,
|
|
1308
|
+
...(keyName ? { keyName } : {}),
|
|
1309
|
+
});
|
|
1310
|
+
const envDir = readString(parsed, "env");
|
|
1311
|
+
let envPath;
|
|
1312
|
+
if (envDir != null) {
|
|
1313
|
+
const outputDir = path.resolve(runtime.cwd, envDir);
|
|
1314
|
+
const force = parsed.booleans.has("force");
|
|
1315
|
+
await assertEnvCanAcceptProvisioning(runtime, outputDir, apiBaseUrl, force);
|
|
1316
|
+
await runtime.mkdir(outputDir);
|
|
1317
|
+
envPath = path.join(outputDir, ".env.local");
|
|
1318
|
+
const existing = (await runtime.exists(envPath))
|
|
1319
|
+
? await runtime.readFile(envPath)
|
|
1320
|
+
: "# Generated by RemoteDraw CLI. Server-side secrets only.\n";
|
|
1321
|
+
const next = updateEnvContents(existing, {
|
|
1322
|
+
REMOTEDRAW_API_BASE_URL: provisioning.apiBaseUrl,
|
|
1323
|
+
REMOTEDRAW_PROJECT_ID: provisioning.project.id,
|
|
1324
|
+
REMOTEDRAW_API_KEY: provisioning.apiKey.value,
|
|
1325
|
+
}, force);
|
|
1326
|
+
if (runtime.writePrivateFile) {
|
|
1327
|
+
await runtime.writePrivateFile(envPath, next);
|
|
1328
|
+
}
|
|
1329
|
+
else {
|
|
1330
|
+
await runtime.writeFile(envPath, next);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
if (format === "json") {
|
|
1334
|
+
return jsonResult({
|
|
1335
|
+
ok: true,
|
|
1336
|
+
command: "project",
|
|
1337
|
+
subcommand: "create",
|
|
1338
|
+
project: provisioning.project,
|
|
1339
|
+
apiKey: {
|
|
1340
|
+
id: provisioning.apiKey.id,
|
|
1341
|
+
name: provisioning.apiKey.name,
|
|
1342
|
+
// Shown exactly once, here. Written to .env.local only with --env.
|
|
1343
|
+
...(envPath ? {} : { value: provisioning.apiKey.value }),
|
|
1344
|
+
},
|
|
1345
|
+
apiBaseUrl: provisioning.apiBaseUrl,
|
|
1346
|
+
...(envPath ? { envPath } : {}),
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
return ok([
|
|
1350
|
+
t("project.created", {
|
|
1351
|
+
name: provisioning.project.name,
|
|
1352
|
+
id: provisioning.project.id,
|
|
1353
|
+
}),
|
|
1354
|
+
` ${provisioning.project.dashboardUrl}`,
|
|
1355
|
+
"",
|
|
1356
|
+
envPath
|
|
1357
|
+
? t("project.keyWritten", { path: envPath })
|
|
1358
|
+
: t("project.keyOnce", { key: provisioning.apiKey.value }),
|
|
1359
|
+
"",
|
|
1360
|
+
t("project.keyRule"),
|
|
1361
|
+
].join("\n"));
|
|
1362
|
+
}
|
|
1363
|
+
function projectHelpText() {
|
|
1364
|
+
return [
|
|
1365
|
+
t("word.usage"),
|
|
1366
|
+
t("project.help.usage"),
|
|
1367
|
+
"",
|
|
1368
|
+
t("project.help.body"),
|
|
1369
|
+
t("project.help.env"),
|
|
1370
|
+
t("project.help.auth"),
|
|
1371
|
+
].join("\n");
|
|
1372
|
+
}
|
|
1373
|
+
async function scanCommand(args, runtime) {
|
|
1374
|
+
const parsed = parseArgs(args, {
|
|
1375
|
+
values: ["path", "format"],
|
|
1376
|
+
booleans: ["help"],
|
|
1377
|
+
});
|
|
1378
|
+
if (parsed.booleans.has("help"))
|
|
1379
|
+
return ok(scanHelpText());
|
|
1380
|
+
const format = outputFormat(parsed);
|
|
1381
|
+
const root = resolveOutputDir(runtime.cwd, parsed);
|
|
1382
|
+
if (!(await runtime.exists(root))) {
|
|
1383
|
+
throw cliError("INVALID_ARGUMENT", "scan.error.missingPath", { path: root });
|
|
1384
|
+
}
|
|
1385
|
+
const report = await scanProject(root, runtime);
|
|
1386
|
+
if (format === "json")
|
|
1387
|
+
return jsonResult(report);
|
|
1388
|
+
return ok(renderScanText(report));
|
|
1389
|
+
}
|
|
1390
|
+
function scanHelpText() {
|
|
1391
|
+
return [
|
|
1392
|
+
t("word.usage"),
|
|
1393
|
+
t("scan.help.usage"),
|
|
1394
|
+
"",
|
|
1395
|
+
t("scan.help.body"),
|
|
1396
|
+
t("scan.help.privacy"),
|
|
1397
|
+
t("scan.help.json"),
|
|
1398
|
+
].join("\n");
|
|
1399
|
+
}
|
|
1258
1400
|
async function agentCommand(args, runtime) {
|
|
1259
1401
|
const parsed = parseArgs(args, {
|
|
1260
1402
|
values: ["path"],
|
|
@@ -1527,7 +1669,7 @@ async function promptForNewProject(parsed, runtime) {
|
|
|
1527
1669
|
const preset = readString(parsed, "preset") == null
|
|
1528
1670
|
? await prompts.select({
|
|
1529
1671
|
message: t("field.preset"),
|
|
1530
|
-
defaultValue: "
|
|
1672
|
+
defaultValue: "sketch",
|
|
1531
1673
|
choices: presetPromptChoices(),
|
|
1532
1674
|
})
|
|
1533
1675
|
: choice(readString(parsed, "preset"), presetChoices, "preset");
|
|
@@ -1788,16 +1930,16 @@ function sdkPromptChoices(target, sender) {
|
|
|
1788
1930
|
}
|
|
1789
1931
|
function presetPromptChoices() {
|
|
1790
1932
|
return [
|
|
1791
|
-
{
|
|
1792
|
-
value: "signature",
|
|
1793
|
-
label: t("choice.preset.signature.label"),
|
|
1794
|
-
hint: t("choice.preset.signature.hint"),
|
|
1795
|
-
},
|
|
1796
1933
|
{
|
|
1797
1934
|
value: "sketch",
|
|
1798
1935
|
label: t("choice.preset.sketch.label"),
|
|
1799
1936
|
hint: t("choice.preset.sketch.hint"),
|
|
1800
1937
|
},
|
|
1938
|
+
{
|
|
1939
|
+
value: "screenMarkup",
|
|
1940
|
+
label: t("choice.preset.screenMarkup.label"),
|
|
1941
|
+
hint: t("choice.preset.screenMarkup.hint"),
|
|
1942
|
+
},
|
|
1801
1943
|
];
|
|
1802
1944
|
}
|
|
1803
1945
|
function packageManagerPromptChoices() {
|
|
@@ -1808,18 +1950,6 @@ function packageManagerPromptChoices() {
|
|
|
1808
1950
|
}
|
|
1809
1951
|
function presetWizardDetails() {
|
|
1810
1952
|
return {
|
|
1811
|
-
signature: {
|
|
1812
|
-
summary: t("choice.preset.signature.summary"),
|
|
1813
|
-
explanation: t("choice.preset.signature.explanation"),
|
|
1814
|
-
docsUrl: DOCS_PAYLOADS,
|
|
1815
|
-
docsLabel: t("choice.preset.signature.docs"),
|
|
1816
|
-
},
|
|
1817
|
-
initials: {
|
|
1818
|
-
summary: t("choice.preset.initials.summary"),
|
|
1819
|
-
explanation: t("choice.preset.initials.explanation"),
|
|
1820
|
-
docsUrl: DOCS_PAYLOADS,
|
|
1821
|
-
docsLabel: t("choice.preset.initials.docs"),
|
|
1822
|
-
},
|
|
1823
1953
|
approval: {
|
|
1824
1954
|
summary: t("choice.preset.approval.summary"),
|
|
1825
1955
|
explanation: t("choice.preset.approval.explanation"),
|
|
@@ -1989,7 +2119,7 @@ function agentOptionCatalog() {
|
|
|
1989
2119
|
`${target}:${sender.value}`,
|
|
1990
2120
|
defaultSdkForChoices(target, sender.value),
|
|
1991
2121
|
]))),
|
|
1992
|
-
preset: "
|
|
2122
|
+
preset: "sketch",
|
|
1993
2123
|
packageManager: "npm",
|
|
1994
2124
|
apiBaseUrl: DEFAULT_REMOTEDRAW_API_BASE_URL,
|
|
1995
2125
|
},
|
|
@@ -2008,7 +2138,7 @@ export function projectSetupDefinition() {
|
|
|
2008
2138
|
target: "web",
|
|
2009
2139
|
sender: "remotedraw-ios",
|
|
2010
2140
|
sdk: "react",
|
|
2011
|
-
preset: "
|
|
2141
|
+
preset: "sketch",
|
|
2012
2142
|
packageManager: "npm",
|
|
2013
2143
|
},
|
|
2014
2144
|
fields: projectSetupFields(),
|
|
@@ -2124,7 +2254,7 @@ function planFromArgs(parsed, options) {
|
|
|
2124
2254
|
const sdk = choice(readString(parsed, "sdk") ??
|
|
2125
2255
|
options.defaults?.sdk ??
|
|
2126
2256
|
defaultSdkForChoices(target, sender), sdkChoices, "sdk");
|
|
2127
|
-
const preset = choice(readString(parsed, "preset") ?? options.defaults?.preset ?? "
|
|
2257
|
+
const preset = choice(readString(parsed, "preset") ?? options.defaults?.preset ?? "sketch", presetChoices, "preset");
|
|
2128
2258
|
const packageManager = choice(readString(parsed, "package-manager") ??
|
|
2129
2259
|
options.defaults?.packageManager ??
|
|
2130
2260
|
"npm", packageManagerChoices, "package-manager");
|
|
@@ -2413,7 +2543,7 @@ function initPackageJson(plan) {
|
|
|
2413
2543
|
}
|
|
2414
2544
|
function configJson(plan) {
|
|
2415
2545
|
return {
|
|
2416
|
-
$schema: "https://
|
|
2546
|
+
$schema: "https://remotedraw.com/schemas/remotedraw.config.json",
|
|
2417
2547
|
appName: plan.appName,
|
|
2418
2548
|
environment: "dev",
|
|
2419
2549
|
target: plan.target,
|
|
@@ -2481,6 +2611,11 @@ function integrationReadme(plan) {
|
|
|
2481
2611
|
}
|
|
2482
2612
|
function reactBackendSessionTs(plan) {
|
|
2483
2613
|
return [
|
|
2614
|
+
"// SERVER-SIDE ONLY. This file reads REMOTEDRAW_API_KEY (an rd_sk_ secret).",
|
|
2615
|
+
"// It must run where secrets live — an API route, a server action, a Convex",
|
|
2616
|
+
"// action, a serverless function — never in browser or app code. If this",
|
|
2617
|
+
"// landed under a Vite/Next client tree, move it to your server before use.",
|
|
2618
|
+
"",
|
|
2484
2619
|
'import { createHttpRemoteDrawApiClient } from "@remotedraw/react";',
|
|
2485
2620
|
'import type { CreateSessionRequest } from "@remotedraw/react";',
|
|
2486
2621
|
"",
|
|
@@ -2668,6 +2803,11 @@ function reactSenderTsx() {
|
|
|
2668
2803
|
}
|
|
2669
2804
|
function svelteBackendSessionTs(plan) {
|
|
2670
2805
|
return [
|
|
2806
|
+
"// SERVER-SIDE ONLY. This file reads REMOTEDRAW_API_KEY (an rd_sk_ secret).",
|
|
2807
|
+
"// It must run where secrets live — an API route, a server action, a Convex",
|
|
2808
|
+
"// action, a serverless function — never in browser or app code. If this",
|
|
2809
|
+
"// landed under a Vite/Next client tree, move it to your server before use.",
|
|
2810
|
+
"",
|
|
2671
2811
|
'import { createHttpRemoteDrawApiClient } from "@remotedraw/svelte";',
|
|
2672
2812
|
'import type { CreateSessionRequest } from "@remotedraw/svelte";',
|
|
2673
2813
|
"",
|
|
@@ -2744,6 +2884,11 @@ function rawHttpSessionTs(plan) {
|
|
|
2744
2884
|
// declares nothing and stays import-free.
|
|
2745
2885
|
const typed = plan.sdk === "js";
|
|
2746
2886
|
return [
|
|
2887
|
+
"// SERVER-SIDE ONLY. This file reads REMOTEDRAW_API_KEY (an rd_sk_ secret).",
|
|
2888
|
+
"// It must run where secrets live — an API route, a server action, a Convex",
|
|
2889
|
+
"// action, a serverless function — never in browser or app code. If this",
|
|
2890
|
+
"// landed under a Vite/Next client tree, move it to your server before use.",
|
|
2891
|
+
"",
|
|
2747
2892
|
...(typed
|
|
2748
2893
|
? [
|
|
2749
2894
|
"import type {",
|
|
@@ -3049,19 +3194,8 @@ export function createSessionPayload(options) {
|
|
|
3049
3194
|
externalId: options.externalId,
|
|
3050
3195
|
markupPreset: options.preset,
|
|
3051
3196
|
target: {
|
|
3052
|
-
kind:
|
|
3197
|
+
kind: PRESETS[options.preset].kind,
|
|
3053
3198
|
label: options.label,
|
|
3054
|
-
...(options.preset === "signature"
|
|
3055
|
-
? {
|
|
3056
|
-
inputMapping: "surface",
|
|
3057
|
-
coordinateSpace: { width: 1600, height: 500 },
|
|
3058
|
-
}
|
|
3059
|
-
: options.preset === "initials"
|
|
3060
|
-
? {
|
|
3061
|
-
inputMapping: "surface",
|
|
3062
|
-
coordinateSpace: { width: 800, height: 500 },
|
|
3063
|
-
}
|
|
3064
|
-
: {}),
|
|
3065
3199
|
metadata: {
|
|
3066
3200
|
descriptor,
|
|
3067
3201
|
},
|
|
@@ -3072,31 +3206,6 @@ export function createSessionPayload(options) {
|
|
|
3072
3206
|
};
|
|
3073
3207
|
}
|
|
3074
3208
|
function descriptorForPreset(preset, label) {
|
|
3075
|
-
if (preset === "signature" || preset === "initials") {
|
|
3076
|
-
return {
|
|
3077
|
-
version: 1,
|
|
3078
|
-
privacy: "metadata-only",
|
|
3079
|
-
surfaceRole: "field",
|
|
3080
|
-
inputIntent: preset,
|
|
3081
|
-
label,
|
|
3082
|
-
components: [
|
|
3083
|
-
{
|
|
3084
|
-
id: preset,
|
|
3085
|
-
role: "field",
|
|
3086
|
-
inputIntent: preset,
|
|
3087
|
-
required: true,
|
|
3088
|
-
bounds: { minX: 0.1, minY: 0.68, maxX: 0.9, maxY: 0.86 },
|
|
3089
|
-
},
|
|
3090
|
-
],
|
|
3091
|
-
phoneHints: {
|
|
3092
|
-
preferredLayout: "signature-pad",
|
|
3093
|
-
preferredTool: "freehand",
|
|
3094
|
-
primaryActionLabel: "Submit",
|
|
3095
|
-
showUndo: true,
|
|
3096
|
-
showClear: true,
|
|
3097
|
-
},
|
|
3098
|
-
};
|
|
3099
|
-
}
|
|
3100
3209
|
if (preset === "approval") {
|
|
3101
3210
|
return {
|
|
3102
3211
|
version: 1,
|
|
@@ -3114,7 +3223,7 @@ function descriptorForPreset(preset, label) {
|
|
|
3114
3223
|
return {
|
|
3115
3224
|
version: 1,
|
|
3116
3225
|
privacy: "metadata-only",
|
|
3117
|
-
surfaceRole:
|
|
3226
|
+
surfaceRole: PRESETS[preset].role,
|
|
3118
3227
|
inputIntent: preset === "pointer" ? "point" : "annotate",
|
|
3119
3228
|
label,
|
|
3120
3229
|
phoneHints: {
|
|
@@ -3126,47 +3235,18 @@ function descriptorForPreset(preset, label) {
|
|
|
3126
3235
|
},
|
|
3127
3236
|
};
|
|
3128
3237
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
}
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
if (preset === "mapMarkup")
|
|
3140
|
-
return "map";
|
|
3141
|
-
if (preset === "screenMarkup" || preset === "pointer")
|
|
3142
|
-
return "screen";
|
|
3143
|
-
return "svg";
|
|
3144
|
-
}
|
|
3145
|
-
function surfaceRoleForPreset(preset) {
|
|
3146
|
-
if (preset === "photoMarkup" || preset === "designReview")
|
|
3147
|
-
return "image";
|
|
3148
|
-
if (preset === "mapMarkup")
|
|
3149
|
-
return "map";
|
|
3150
|
-
if (preset === "screenMarkup" || preset === "pointer")
|
|
3151
|
-
return "screen";
|
|
3152
|
-
if (preset === "sketch")
|
|
3153
|
-
return "canvas";
|
|
3154
|
-
return "document";
|
|
3155
|
-
}
|
|
3238
|
+
const PRESETS = {
|
|
3239
|
+
approval: { kind: "field", role: "document", label: "Quick approval" },
|
|
3240
|
+
sketch: { kind: "svg", role: "canvas", label: "Sketch input" },
|
|
3241
|
+
photoMarkup: { kind: "image", role: "image", label: "Photo annotation" },
|
|
3242
|
+
pdfMarkup: { kind: "pdf", role: "document", label: "PDF annotation" },
|
|
3243
|
+
mapMarkup: { kind: "map", role: "map", label: "Map annotation" },
|
|
3244
|
+
screenMarkup: { kind: "screen", role: "screen", label: "Screen annotation" },
|
|
3245
|
+
designReview: { kind: "image", role: "image", label: "Design review" },
|
|
3246
|
+
pointer: { kind: "screen", role: "screen", label: "Pointer input" },
|
|
3247
|
+
};
|
|
3156
3248
|
function labelForPreset(preset) {
|
|
3157
|
-
|
|
3158
|
-
signature: "Customer signature",
|
|
3159
|
-
initials: "Customer initials",
|
|
3160
|
-
approval: "Quick approval",
|
|
3161
|
-
sketch: "Sketch input",
|
|
3162
|
-
photoMarkup: "Photo annotation",
|
|
3163
|
-
pdfMarkup: "PDF annotation",
|
|
3164
|
-
mapMarkup: "Map annotation",
|
|
3165
|
-
screenMarkup: "Screen annotation",
|
|
3166
|
-
designReview: "Design review",
|
|
3167
|
-
pointer: "Pointer input",
|
|
3168
|
-
};
|
|
3169
|
-
return labels[preset];
|
|
3249
|
+
return PRESETS[preset].label;
|
|
3170
3250
|
}
|
|
3171
3251
|
function curlForCreateInput(apiBaseUrl, payload) {
|
|
3172
3252
|
return [
|
|
@@ -3313,7 +3393,7 @@ function planDefaultsForExample(example) {
|
|
|
3313
3393
|
target: "web",
|
|
3314
3394
|
sender: "remotedraw-ios",
|
|
3315
3395
|
sdk: "react",
|
|
3316
|
-
preset: "
|
|
3396
|
+
preset: "sketch",
|
|
3317
3397
|
};
|
|
3318
3398
|
}
|
|
3319
3399
|
function scaffoldSummary(verb, plan, outputDir, written, dryRun) {
|
|
@@ -3357,6 +3437,12 @@ function scaffoldJsonResult(command, plan, outputDir, files, parsed, provisionin
|
|
|
3357
3437
|
...(plan.apiBaseUrl.includes("<deployment>")
|
|
3358
3438
|
? [t("cloud.warning.placeholder")]
|
|
3359
3439
|
: []),
|
|
3440
|
+
// The backend helper is written under src/ because the scaffold has no
|
|
3441
|
+
// idea where this project's server lives. Say so, every time, or a Vite
|
|
3442
|
+
// app ships its key.
|
|
3443
|
+
...(plan.target === "web" && plan.sdk !== "swift"
|
|
3444
|
+
? [t("cloud.warning.clientTree")]
|
|
3445
|
+
: []),
|
|
3360
3446
|
...(offline
|
|
3361
3447
|
? [t("cloud.warning.offline")]
|
|
3362
3448
|
: dryRun
|
package/dist/cloud.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export declare const DEFAULT_REMOTEDRAW_API_BASE_URL = "https://api.remotedraw.c
|
|
|
2
2
|
export type CloudRuntime = {
|
|
3
3
|
env: Record<string, string | undefined>;
|
|
4
4
|
isInteractive?: boolean;
|
|
5
|
-
fetch?:
|
|
5
|
+
fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
6
6
|
exists: (filePath: string) => boolean | Promise<boolean>;
|
|
7
7
|
readFile: (filePath: string) => Promise<string>;
|
|
8
8
|
writeFile: (filePath: string, contents: string) => Promise<void>;
|
package/dist/cloud.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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"}
|