pointer-feedback 0.2.0 → 0.2.1
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 +30 -15
- package/dist/cli.js +147 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ pointer init --server https://api.pointer.moamen.work --key ptr_... --project my
|
|
|
31
31
|
|
|
32
32
|
`init` only expects these files to be shared via git: **`.pointer/config.json`**, **`.pointer/stack.json`**,
|
|
33
33
|
and — in a multi-project repo (see **Monorepos** below) — every **`.pointer/projects/<key>.stack.json`**.
|
|
34
|
-
Everything else (`pointer.sh`, `manifest.json`, and — only if you opted into `--
|
|
34
|
+
Everything else (`pointer.sh`, `manifest.json`, and — only if you opted into `--scope repo` —
|
|
35
35
|
`credentials.env`) is derived or per-machine and stays gitignored, along with every skill layout the
|
|
36
36
|
CLI can write: `.claude/skills/pointer-init/`, `.claude/skills/pointer-feedback/` (Claude Code),
|
|
37
37
|
`.cursor/rules/pointer-init.md`, `.cursor/rules/pointer-feedback.md` (Cursor),
|
|
@@ -175,23 +175,31 @@ its own `index.html` but no `project.json`) instead of asking about the repo roo
|
|
|
175
175
|
|
|
176
176
|
### Authentication
|
|
177
177
|
|
|
178
|
-
Authenticate **once per machine**, not once per repo. `pointer login`
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
178
|
+
Authenticate **once per machine**, not once per repo. `pointer login` — with no `--key`, on a real
|
|
179
|
+
terminal — opens your browser to sign in (mirrors `gh auth login`): it prints a link and a short
|
|
180
|
+
code, waits for you to approve it in the dashboard, and saves the personal API key it hands back to
|
|
181
|
+
a global, per-machine credential store. Pass `--key <key>` to skip the browser and validate a pasted
|
|
182
|
+
key instead (from your profile page or the dashboard's quick-start guide). Every other command
|
|
183
|
+
(`init` in join mode, `doctor`, `apply`, `list`, `mcp`, and `.pointer/pointer.sh`) then finds
|
|
184
|
+
whichever key was saved without being asked again — in this repo, or any other repo on the same
|
|
185
|
+
machine, against the same server.
|
|
182
186
|
|
|
183
187
|
**Resolution order**, identical everywhere a key is needed:
|
|
184
188
|
|
|
185
189
|
1. **`POINTER_API_KEY`** environment variable — the right choice for CI, and always wins outright.
|
|
186
190
|
2. This repo's **`.pointer/credentials.env`** — written only when you opt out of the global store
|
|
187
|
-
(`--
|
|
191
|
+
(`--scope repo`, or choosing "Repo" at the prompt below; `--local-credentials` is the older alias).
|
|
188
192
|
3. The **global store**: `~/.config/pointer/credentials.json` (honours `$XDG_CONFIG_HOME`; on
|
|
189
193
|
Windows, `%APPDATA%\pointer\credentials.json`), keyed by server, mode `0600`.
|
|
190
194
|
|
|
191
195
|
```bash
|
|
192
196
|
# Once per machine, per server:
|
|
193
197
|
pointer login --server https://api.pointer.moamen.work
|
|
194
|
-
#
|
|
198
|
+
# Open this link and enter the code to sign in:
|
|
199
|
+
# https://app.pointer.moamen.work/cli-login?code=ABCD-EFGH
|
|
200
|
+
# Code: ABCD-EFGH
|
|
201
|
+
# Waiting for approval… (Ctrl+C to cancel)
|
|
202
|
+
# ✔ Signed in to https://api.pointer.moamen.work as Jane Doe (jane@example.com) — saved for all repos on this machine
|
|
195
203
|
|
|
196
204
|
pointer whoami
|
|
197
205
|
# https://api.pointer.moamen.work — Jane Doe (jane@example.com) — key source: global store
|
|
@@ -199,17 +207,24 @@ pointer whoami
|
|
|
199
207
|
pointer logout # removes this machine's saved key for a server
|
|
200
208
|
```
|
|
201
209
|
|
|
202
|
-
- **`pointer login [--server <url>] [--key <key>]`** — resolves the server from
|
|
203
|
-
this repo's `.pointer/config.json`, then `$POINTER_SERVER`, then the build
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
- **`pointer login [--server <url>] [--key <key>] [--no-browser]`** — resolves the server from
|
|
211
|
+
`--server`, then this repo's `.pointer/config.json`, then `$POINTER_SERVER`, then the build
|
|
212
|
+
default. With no `--key` it runs the browser sign-in flow above (`--no-browser` prints the
|
|
213
|
+
link/code but skips trying to open a browser); `--key <key>` validates a pasted key instead,
|
|
214
|
+
exactly like `init` does (`/api/auth/login-with-key` + `/api/auth/me`). Either way the resulting
|
|
215
|
+
key is saved to the global store (or `.pointer/credentials.env` with `--scope repo`).
|
|
206
216
|
- **`pointer logout [--server <url>]`** — removes this machine's saved entry for that server. Never
|
|
207
217
|
touches a repo's own `.pointer/credentials.env`.
|
|
208
218
|
- **`pointer whoami [--server <url>] [--json]`** — prints the server, the signed-in account, and
|
|
209
219
|
which source answered the key (`env` / `repo` / `global`) — **never the key itself**.
|
|
210
220
|
|
|
221
|
+
**`init`'s first-run sign-in.** When no key resolves from anywhere (env, repo, or global store) and
|
|
222
|
+
`--key` wasn't passed, an interactive `init` asks how to sign in — "Sign in in your browser
|
|
223
|
+
(recommended)" (the same device-code flow as `pointer login`) or "Paste an API key" (today's hidden
|
|
224
|
+
prompt). `--yes`/`--json` skip the question and require `--key`.
|
|
225
|
+
|
|
211
226
|
**`init` and the global store.** A first install that authenticates a key it did not already trust
|
|
212
|
-
(typed interactively, or passed via `--key`) asks:
|
|
227
|
+
(typed interactively, signed in via the browser, or passed via `--key`) asks:
|
|
213
228
|
|
|
214
229
|
```
|
|
215
230
|
Save this key for all repos on this machine? (Y/n)
|
|
@@ -217,7 +232,7 @@ Save this key for all repos on this machine? (Y/n)
|
|
|
217
232
|
|
|
218
233
|
Answering yes (the default, and also the default under `--yes`/`--json` when `--key` is given)
|
|
219
234
|
saves it globally and writes **no** `.pointer/credentials.env` at all — there is nothing repo-local
|
|
220
|
-
to gitignore, review, or accidentally commit.
|
|
235
|
+
to gitignore, review, or accidentally commit. Choosing "Repo" at the prompt, or passing **`--scope repo`** (alias `--local-credentials`),
|
|
221
236
|
keeps the pre-global-store behaviour: the key is written to `.pointer/credentials.env` instead
|
|
222
237
|
(still gitignored, still per-machine). A join (`init` run again in an already-configured repo) never
|
|
223
238
|
even asks, either way: it tries `resolveApiKey`'s three sources first and only prompts when none of
|
|
@@ -226,7 +241,7 @@ them resolve.
|
|
|
226
241
|
**CI**: set `POINTER_API_KEY` — it always wins, and nothing is written anywhere.
|
|
227
242
|
|
|
228
243
|
**Multiple accounts on one machine** (e.g. a personal key for most repos, a service account for
|
|
229
|
-
one): run `pointer init --key <key> --
|
|
244
|
+
one): run `pointer login --scope repo` in that repo, or `pointer init --key <key> --scope repo` (or `pointer login` normally, then override
|
|
230
245
|
per-repo with `.pointer/credentials.env`) for the repo that needs the different key — the repo-local
|
|
231
246
|
file wins over the global store for that repo only.
|
|
232
247
|
|
|
@@ -322,7 +337,7 @@ pointer reply 12 "Investigating this now."
|
|
|
322
337
|
### `pointer mcp`
|
|
323
338
|
Run the Model Context Protocol (MCP) server over standard I/O for AI coding agents.
|
|
324
339
|
|
|
325
|
-
Exposes typed tools to
|
|
340
|
+
Exposes typed tools to your AI tool over MCP — any MCP-compatible environment — without exposing API keys to the model context.
|
|
326
341
|
|
|
327
342
|
#### Configuration (User-Level, Do Not Commit)
|
|
328
343
|
|
package/dist/cli.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_build_constants = __esm({
|
|
|
15
15
|
"src/build-constants.ts"() {
|
|
16
16
|
"use strict";
|
|
17
17
|
BUILD_DEFAULT_SERVER = true ? "https://api.pointer.moamen.work" : "https://api.pointer.moamen.work";
|
|
18
|
-
BUILD_CLI_VERSION = true ? "0.2.
|
|
18
|
+
BUILD_CLI_VERSION = true ? "0.2.1" : "0.0.0-dev";
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
|
|
@@ -3067,6 +3067,65 @@ function summarizeDesignTokens(tokens, libraries) {
|
|
|
3067
3067
|
|
|
3068
3068
|
// src/commands/init.ts
|
|
3069
3069
|
init_credentials();
|
|
3070
|
+
|
|
3071
|
+
// src/device-login.ts
|
|
3072
|
+
init_api();
|
|
3073
|
+
import { spawn } from "node:child_process";
|
|
3074
|
+
import { hostname } from "node:os";
|
|
3075
|
+
function openBrowser(url) {
|
|
3076
|
+
try {
|
|
3077
|
+
let child;
|
|
3078
|
+
if (process.platform === "darwin") {
|
|
3079
|
+
child = spawn("open", [url], { detached: true, stdio: "ignore" });
|
|
3080
|
+
} else if (process.platform === "win32") {
|
|
3081
|
+
child = spawn("cmd", ["/c", "start", '""', url], { detached: true, stdio: "ignore", windowsHide: true });
|
|
3082
|
+
} else {
|
|
3083
|
+
child = spawn("xdg-open", [url], { detached: true, stdio: "ignore" });
|
|
3084
|
+
}
|
|
3085
|
+
child.unref();
|
|
3086
|
+
child.on("error", () => {
|
|
3087
|
+
});
|
|
3088
|
+
} catch {
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
function sleep(ms) {
|
|
3092
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
3093
|
+
}
|
|
3094
|
+
async function runDeviceLogin(server, options = {}) {
|
|
3095
|
+
const clientName = options.clientName ?? `pointer-feedback CLI on ${hostname()}`;
|
|
3096
|
+
const start = await api(server, "/api/auth/device/start", {
|
|
3097
|
+
method: "POST",
|
|
3098
|
+
body: { clientName }
|
|
3099
|
+
});
|
|
3100
|
+
console.log("Open this link and enter the code to sign in:");
|
|
3101
|
+
console.log(` ${start.verificationUrl}`);
|
|
3102
|
+
console.log(` Code: ${start.userCode}`);
|
|
3103
|
+
console.log("Waiting for approval\u2026 (Ctrl+C to cancel)");
|
|
3104
|
+
if (!options.noBrowser)
|
|
3105
|
+
openBrowser(start.verificationUrl);
|
|
3106
|
+
const deadline = Date.now() + start.expiresInSeconds * 1e3;
|
|
3107
|
+
const intervalMs = Math.max(1, start.intervalSeconds) * 1e3;
|
|
3108
|
+
while (Date.now() < deadline) {
|
|
3109
|
+
await sleep(intervalMs);
|
|
3110
|
+
const poll = await api(server, "/api/auth/device/poll", {
|
|
3111
|
+
method: "POST",
|
|
3112
|
+
body: { deviceCode: start.deviceCode }
|
|
3113
|
+
});
|
|
3114
|
+
if (poll.status === "approved") {
|
|
3115
|
+
if (!poll.apiKey) {
|
|
3116
|
+
return { ok: false, reason: "expired" };
|
|
3117
|
+
}
|
|
3118
|
+
return { ok: true, result: { apiKey: poll.apiKey, displayName: poll.displayName, email: poll.email } };
|
|
3119
|
+
}
|
|
3120
|
+
if (poll.status === "denied")
|
|
3121
|
+
return { ok: false, reason: "denied" };
|
|
3122
|
+
if (poll.status === "expired" || poll.status === "unknown")
|
|
3123
|
+
return { ok: false, reason: "expired" };
|
|
3124
|
+
}
|
|
3125
|
+
return { ok: false, reason: "expired" };
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
// src/commands/init.ts
|
|
3070
3129
|
async function initCommand(cwd2, options = {}) {
|
|
3071
3130
|
const isYes = options["yes"] || options["json"];
|
|
3072
3131
|
const isJson = options["json"];
|
|
@@ -3090,7 +3149,12 @@ async function initCommand(cwd2, options = {}) {
|
|
|
3090
3149
|
if (!isYes && !options["server"] && !config.server) {
|
|
3091
3150
|
server = await ask("Server URL", { default: server });
|
|
3092
3151
|
}
|
|
3093
|
-
const
|
|
3152
|
+
const scopeFlag = typeof options["scope"] === "string" ? String(options["scope"]).toLowerCase() : void 0;
|
|
3153
|
+
if (scopeFlag !== void 0 && scopeFlag !== "global" && scopeFlag !== "repo") {
|
|
3154
|
+
console.error(`Invalid --scope "${options["scope"]}". Valid values: global, repo.`);
|
|
3155
|
+
process.exit(2);
|
|
3156
|
+
}
|
|
3157
|
+
const localCredentialsFlag = Boolean(options["local-credentials"]) || scopeFlag === "repo";
|
|
3094
3158
|
let key = options["key"];
|
|
3095
3159
|
let keySource = null;
|
|
3096
3160
|
if (!key) {
|
|
@@ -3165,6 +3229,37 @@ async function initCommand(cwd2, options = {}) {
|
|
|
3165
3229
|
}
|
|
3166
3230
|
} else {
|
|
3167
3231
|
let attempts = 0;
|
|
3232
|
+
if (!key) {
|
|
3233
|
+
const choice = await select("How do you want to sign in?", [
|
|
3234
|
+
"Sign in in your browser (recommended)",
|
|
3235
|
+
"Paste an API key"
|
|
3236
|
+
]);
|
|
3237
|
+
if (choice.startsWith("Sign in in your browser")) {
|
|
3238
|
+
const outcome = await runDeviceLogin(server, { noBrowser: options["no-browser"] === true });
|
|
3239
|
+
if (!outcome.ok) {
|
|
3240
|
+
if (outcome.reason === "denied") {
|
|
3241
|
+
console.error("Sign-in was denied.");
|
|
3242
|
+
} else {
|
|
3243
|
+
console.error("The sign-in code expired. Run `pointer init` again.");
|
|
3244
|
+
}
|
|
3245
|
+
process.exit(3);
|
|
3246
|
+
}
|
|
3247
|
+
key = outcome.result.apiKey;
|
|
3248
|
+
try {
|
|
3249
|
+
const login = await api(server, "/api/auth/login-with-key", {
|
|
3250
|
+
method: "POST",
|
|
3251
|
+
body: { apiKey: key }
|
|
3252
|
+
});
|
|
3253
|
+
if (login?.status !== "ok" || !login?.token)
|
|
3254
|
+
throw new Error(login?.status || "invalid");
|
|
3255
|
+
token = login.token;
|
|
3256
|
+
me = login.user ?? await api(server, "/api/auth/me", { token });
|
|
3257
|
+
} catch {
|
|
3258
|
+
console.error("Invalid API key.");
|
|
3259
|
+
process.exit(3);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3168
3263
|
while (!me) {
|
|
3169
3264
|
if (!key) {
|
|
3170
3265
|
key = await ask(`API key (from ${product} -> profile -> API key; input hidden)`, { secret: true });
|
|
@@ -3195,9 +3290,12 @@ async function initCommand(cwd2, options = {}) {
|
|
|
3195
3290
|
let writeLocalCreds = keySource !== "global" && keySource !== "env";
|
|
3196
3291
|
if (freshlyAuthenticated) {
|
|
3197
3292
|
let saveGlobally = !localCredentialsFlag;
|
|
3198
|
-
if (saveGlobally && !isYes) {
|
|
3199
|
-
const
|
|
3200
|
-
|
|
3293
|
+
if (saveGlobally && !isYes && scopeFlag === void 0) {
|
|
3294
|
+
const choice = await select("Where should this API key be stored?", [
|
|
3295
|
+
"Global \u2014 this machine, every repo (~/.config/pointer/credentials.json)",
|
|
3296
|
+
"Repo \u2014 .pointer/credentials.env in this repo only (gitignored)"
|
|
3297
|
+
]);
|
|
3298
|
+
saveGlobally = choice.startsWith("Global");
|
|
3201
3299
|
}
|
|
3202
3300
|
if (saveGlobally) {
|
|
3203
3301
|
await saveGlobalCredential(server, { apiKey: key, email: me?.email, displayName: me?.displayName });
|
|
@@ -3465,7 +3563,7 @@ and the pointer-init skill uses them to mount the widget for you afterwards.
|
|
|
3465
3563
|
If you know the file, name it and re-run \u2014 that always wins over detection:
|
|
3466
3564
|
npx -y pointer-feedback init --html path/to/index.html
|
|
3467
3565
|
Otherwise the pointer-init skill was installed for ${tool}; run it and it will mount the widget:
|
|
3468
|
-
|
|
3566
|
+
/pointer-init (or @pointer-init, depending on your AI tool)
|
|
3469
3567
|
Config is already saved in .pointer/config.json, so neither will ask for the key or project again.`);
|
|
3470
3568
|
}
|
|
3471
3569
|
}
|
|
@@ -11778,31 +11876,34 @@ async function loginCommand(cwd2, options = {}) {
|
|
|
11778
11876
|
console.error("Invalid API key.");
|
|
11779
11877
|
process.exit(3);
|
|
11780
11878
|
}
|
|
11781
|
-
} else {
|
|
11782
|
-
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11786
|
-
|
|
11787
|
-
|
|
11788
|
-
body: { apiKey: key }
|
|
11789
|
-
});
|
|
11790
|
-
if (login?.status !== "ok" || !login?.token)
|
|
11791
|
-
throw new Error(login?.status || "invalid");
|
|
11792
|
-
me = login.user ?? await api(server, "/api/auth/me", { token: login.token });
|
|
11793
|
-
} catch {
|
|
11794
|
-
attempts++;
|
|
11795
|
-
if (attempts >= 3) {
|
|
11796
|
-
console.error("Invalid API key.");
|
|
11797
|
-
process.exit(3);
|
|
11798
|
-
}
|
|
11799
|
-
console.error("Invalid API key. Try again.");
|
|
11879
|
+
} else if (process.stdin.isTTY || options["no-browser"] === true) {
|
|
11880
|
+
const outcome = await runDeviceLogin(server, { noBrowser: options["no-browser"] === true });
|
|
11881
|
+
if (!outcome.ok) {
|
|
11882
|
+
if (outcome.reason === "denied") {
|
|
11883
|
+
console.error("Sign-in was denied.");
|
|
11884
|
+
} else {
|
|
11885
|
+
console.error("The sign-in code expired. Run `pointer login` again.");
|
|
11800
11886
|
}
|
|
11887
|
+
process.exit(3);
|
|
11801
11888
|
}
|
|
11802
|
-
|
|
11889
|
+
key = outcome.result.apiKey;
|
|
11890
|
+
me = { displayName: outcome.result.displayName, email: outcome.result.email };
|
|
11891
|
+
} else {
|
|
11892
|
+
console.error("No key provided and no terminal to sign in from \u2014 run `pointer login --key <key>` or set POINTER_API_KEY.");
|
|
11893
|
+
process.exit(2);
|
|
11894
|
+
}
|
|
11895
|
+
const scope = typeof options["scope"] === "string" ? String(options["scope"]).toLowerCase() : "global";
|
|
11896
|
+
if (scope !== "global" && scope !== "repo") {
|
|
11897
|
+
console.error(`Invalid --scope "${options["scope"]}". Valid values: global, repo.`);
|
|
11898
|
+
process.exit(2);
|
|
11803
11899
|
}
|
|
11804
|
-
await saveGlobalCredential(server, { apiKey: key, email: me?.email, displayName: me?.displayName });
|
|
11805
11900
|
const who = me?.displayName ? `${me.displayName}${me?.email ? ` (${me.email})` : ""}` : me?.email ?? "you";
|
|
11901
|
+
if (scope === "repo") {
|
|
11902
|
+
await writeCredentials(root, key, { server });
|
|
11903
|
+
console.log(`\u2714 Signed in to ${server} as ${who} \u2014 saved to .pointer/credentials.env (this repo only; overrides the global store here)`);
|
|
11904
|
+
process.exit(0);
|
|
11905
|
+
}
|
|
11906
|
+
await saveGlobalCredential(server, { apiKey: key, email: me?.email, displayName: me?.displayName });
|
|
11806
11907
|
console.log(`\u2714 Signed in to ${server} as ${who} \u2014 saved for all repos on this machine`);
|
|
11807
11908
|
process.exit(0);
|
|
11808
11909
|
}
|
|
@@ -11896,7 +11997,8 @@ function parseArgs(args) {
|
|
|
11896
11997
|
"dry-run",
|
|
11897
11998
|
"no-commit",
|
|
11898
11999
|
"version",
|
|
11899
|
-
"local-credentials"
|
|
12000
|
+
"local-credentials",
|
|
12001
|
+
"no-browser"
|
|
11900
12002
|
]);
|
|
11901
12003
|
for (let i = 0; i < args.length; i++) {
|
|
11902
12004
|
const arg = args[i];
|
|
@@ -11986,8 +12088,11 @@ Options:
|
|
|
11986
12088
|
--no-skills Skip skills installation
|
|
11987
12089
|
--no-design Skip design token detection
|
|
11988
12090
|
--source-map Wire in the Vite plugin that stamps component source hashes
|
|
11989
|
-
--
|
|
11990
|
-
|
|
12091
|
+
--scope <global|repo> Where the API key is stored: global (default \u2014 this machine, all repos,
|
|
12092
|
+
~/.config/pointer/credentials.json) or repo (.pointer/credentials.env,
|
|
12093
|
+
gitignored, this repo only). --local-credentials is an alias for --scope repo
|
|
12094
|
+
--no-browser When signing in in the browser (first run, no key resolved yet), print
|
|
12095
|
+
the link/code but don't try to open a browser
|
|
11991
12096
|
-y, --yes Non-interactive
|
|
11992
12097
|
--json JSON output (implies --yes)
|
|
11993
12098
|
-h, --help Show help
|
|
@@ -12000,14 +12105,22 @@ Options:
|
|
|
12000
12105
|
console.log(`
|
|
12001
12106
|
Usage: pointer login [options]
|
|
12002
12107
|
|
|
12003
|
-
Authenticate once per machine
|
|
12108
|
+
Authenticate once per machine and save the result to
|
|
12004
12109
|
~/.config/pointer/credentials.json (honours $XDG_CONFIG_HOME / $POINTER_CONFIG_DIR), keyed by
|
|
12005
12110
|
server. Every repo on this machine then resolves a key for that server without being asked again.
|
|
12006
12111
|
|
|
12112
|
+
With no --key on a real terminal, opens your browser to sign in (mirrors \`gh auth login\`): prints
|
|
12113
|
+
a link and a short code, waits for you to approve it in the dashboard, then saves the personal API
|
|
12114
|
+
key it hands back. Pass --key to skip the browser and validate a pasted key instead, unchanged from
|
|
12115
|
+
before.
|
|
12116
|
+
|
|
12007
12117
|
Options:
|
|
12008
|
-
--server <url>
|
|
12009
|
-
--key <key>
|
|
12010
|
-
-
|
|
12118
|
+
--server <url> Server URL (default: this repo's .pointer/config.json, then $POINTER_SERVER)
|
|
12119
|
+
--key <key> API key \u2014 skips the browser flow entirely
|
|
12120
|
+
--no-browser Print the sign-in link/code but don't try to open a browser
|
|
12121
|
+
--scope <global|repo> global (default): save for every repo on this machine;
|
|
12122
|
+
repo: write .pointer/credentials.env in the current repo only
|
|
12123
|
+
-h, --help Show this help
|
|
12011
12124
|
`);
|
|
12012
12125
|
process.exit(0);
|
|
12013
12126
|
}
|
package/package.json
CHANGED