uc-config 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/CHANGELOG.md +48 -0
- package/README.md +45 -2
- package/dist/cli.js +74 -19
- package/dist/init.d.ts +9 -1
- package/dist/init.js +65 -5
- package/docs/cli.md +1 -0
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Each release says whether upgrading needs any **action**. To upgrade a config
|
|
4
|
+
workspace:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install uc-config@latest
|
|
8
|
+
npx uc-config init --refresh-docs
|
|
9
|
+
npx uc-config compile && npx uc-config plan # must show 0 operations
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 0.2.2
|
|
13
|
+
|
|
14
|
+
Action required: optional. Run `npx uc-config init --refresh-docs` to get the
|
|
15
|
+
new AGENTS.md sections.
|
|
16
|
+
|
|
17
|
+
- Multiple remotes: documented as one folder per remote. `init` refuses to add
|
|
18
|
+
a second remote to a folder, and commands that can't pick a target list the
|
|
19
|
+
targets the folder has.
|
|
20
|
+
- `init` ends by suggesting the prompt "Set up my Remote 3" (the address is
|
|
21
|
+
already saved).
|
|
22
|
+
- Docs: dock or wake the remote during setup; AGENTS.md says what to do when the
|
|
23
|
+
remote stops responding.
|
|
24
|
+
|
|
25
|
+
## 0.2.1
|
|
26
|
+
|
|
27
|
+
Action required: run `npx uc-config init --refresh-docs`. It updates the
|
|
28
|
+
scaffolded AGENTS.md, whose upgrade instructions were wrong.
|
|
29
|
+
|
|
30
|
+
- `init --refresh-docs` updates AGENTS.md and CLAUDE.md to the installed
|
|
31
|
+
version. Files you edited are kept, and the new version is written beside
|
|
32
|
+
them as `.new`.
|
|
33
|
+
- `doctor` prints a notice when a newer version is published. Set
|
|
34
|
+
`UC_NO_UPDATE_CHECK=1` to disable it.
|
|
35
|
+
- The scaffolded upgrade instructions use `npm install uc-config@latest`.
|
|
36
|
+
`npm update` doesn't move between 0.x minor versions.
|
|
37
|
+
|
|
38
|
+
## 0.2.0
|
|
39
|
+
|
|
40
|
+
Action required: none.
|
|
41
|
+
|
|
42
|
+
- `init` asks for the remote's IP and the web configurator PIN, then connects
|
|
43
|
+
and authenticates. It can be rerun safely.
|
|
44
|
+
- `init` writes CLAUDE.md, which points Claude Code at AGENTS.md.
|
|
45
|
+
|
|
46
|
+
## 0.1.0
|
|
47
|
+
|
|
48
|
+
First release.
|
package/README.md
CHANGED
|
@@ -24,7 +24,12 @@ hardware. Humans can use it directly too.
|
|
|
24
24
|
- On the remote, enable the web configurator: **Settings → Profile → Web
|
|
25
25
|
configurator**. Note the **PIN** it shows.
|
|
26
26
|
- Find the remote's **IP address**. It's shown in the remote's network
|
|
27
|
-
settings, or in your router's device list. The computer you use must be on
|
|
27
|
+
settings, or in your router's device list. The computer you use must be on
|
|
28
|
+
the same network as the remote.
|
|
29
|
+
- **Dock the remote** (or keep picking it up) during setup. It doesn't need the
|
|
30
|
+
dock to work, but it goes to sleep when idle and drops off Wi-Fi, which
|
|
31
|
+
interrupts setup. The Integration Manager's web page is also only available
|
|
32
|
+
while docked.
|
|
28
33
|
|
|
29
34
|
### 2. Create your config folder
|
|
30
35
|
|
|
@@ -51,7 +56,10 @@ repo.
|
|
|
51
56
|
Start your coding agent (Claude Code, Codex, Cursor, etc.) in that folder and
|
|
52
57
|
prompt:
|
|
53
58
|
|
|
54
|
-
> Set up my Remote 3
|
|
59
|
+
> Set up my Remote 3
|
|
60
|
+
|
|
61
|
+
`init` already saved the remote's address, so you don't need to repeat it. (If
|
|
62
|
+
you skipped the IP prompt, include it: "Set up my Remote 3 at 192.168.1.50".)
|
|
55
63
|
|
|
56
64
|
The agent imports your current setup into `remote.config.ts` and records which
|
|
57
65
|
resources it manages. This writes nothing to the remote.
|
|
@@ -82,6 +90,41 @@ Ask your agent for changes in plain language, for example:
|
|
|
82
90
|
The agent shows a plan of what will change before applying it. After you update
|
|
83
91
|
an integration in the Integration Manager, ask the agent to run diagnostics.
|
|
84
92
|
|
|
93
|
+
## Multiple remotes
|
|
94
|
+
|
|
95
|
+
Use **one folder per remote**:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
mkdir -p remotes/living-room && cd remotes/living-room && npx uc-config init
|
|
99
|
+
mkdir -p remotes/bedroom && cd remotes/bedroom && npx uc-config init
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Each folder has its own `remote.config.ts`, state and API key, and an agent
|
|
103
|
+
working in one folder can't touch the other remote. The folders can share one
|
|
104
|
+
private git repo. Two remotes rarely have identical configs, because entity IDs
|
|
105
|
+
include each remote's integration IDs; to share a macro or layout, put it in a
|
|
106
|
+
common `.ts` file and import it, using each folder's own `generated/devices.ts`
|
|
107
|
+
for the IDs.
|
|
108
|
+
|
|
109
|
+
`init` refuses to add a second remote to a folder that already has one.
|
|
110
|
+
|
|
111
|
+
## Updating
|
|
112
|
+
|
|
113
|
+
Ask your agent to "update uc-config", or run in your config folder:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
npm install uc-config@latest
|
|
117
|
+
npx uc-config init --refresh-docs # refresh AGENTS.md / CLAUDE.md
|
|
118
|
+
npx uc-config compile && npx uc-config plan # must show 0 operations
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Use `npm install uc-config@latest` rather than `npm update`: before 1.0,
|
|
122
|
+
`npm update` doesn't move between minor versions (0.2 → 0.3). `--refresh-docs`
|
|
123
|
+
keeps files you've edited and writes the new version beside them as `.new`.
|
|
124
|
+
`doctor` tells you when a newer version is available. See
|
|
125
|
+
[CHANGELOG.md](CHANGELOG.md) for what changed and whether a release needs any
|
|
126
|
+
action.
|
|
127
|
+
|
|
85
128
|
## Requirements
|
|
86
129
|
|
|
87
130
|
- Node.js 22+ and npm
|
package/dist/cli.js
CHANGED
|
@@ -23,23 +23,27 @@ const program = new Command()
|
|
|
23
23
|
.description("TypeScript configuration and provisioning for Unfolded Circle Remote 3")
|
|
24
24
|
.version(pkgVersion)
|
|
25
25
|
.option("--workspace <path>", "project directory", process.cwd());
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const dir = resolve(ws > 0 ? process.argv[ws + 1] : process.cwd());
|
|
26
|
+
function workspaceTargets(dir) {
|
|
27
|
+
if (!dir) {
|
|
28
|
+
const ws = process.argv.indexOf("--workspace");
|
|
29
|
+
dir = resolve(ws > 0 ? process.argv[ws + 1] : process.cwd());
|
|
30
|
+
}
|
|
32
31
|
try {
|
|
33
|
-
|
|
32
|
+
return readdirSync(join(dir, ".uc", "targets"))
|
|
34
33
|
.filter((f) => f.endsWith(".json"))
|
|
35
|
-
.map((f) => f.slice(0, -5))
|
|
36
|
-
|
|
37
|
-
return names[0];
|
|
34
|
+
.map((f) => f.slice(0, -5))
|
|
35
|
+
.sort();
|
|
38
36
|
}
|
|
39
37
|
catch {
|
|
40
|
-
// no targets yet
|
|
38
|
+
return []; // no targets yet
|
|
41
39
|
}
|
|
42
|
-
|
|
40
|
+
}
|
|
41
|
+
// UC_TARGET, else the workspace's only target, else "home".
|
|
42
|
+
function implicitTarget() {
|
|
43
|
+
if (process.env.UC_TARGET)
|
|
44
|
+
return process.env.UC_TARGET;
|
|
45
|
+
const names = workspaceTargets();
|
|
46
|
+
return names.length === 1 ? names[0] : "home";
|
|
43
47
|
}
|
|
44
48
|
const defaultTarget = implicitTarget();
|
|
45
49
|
const root = () => resolve(program.opts().workspace);
|
|
@@ -58,8 +62,12 @@ async function load(name) {
|
|
|
58
62
|
target = await readJson(targetFile(name));
|
|
59
63
|
}
|
|
60
64
|
catch (e) {
|
|
61
|
-
if (e.code === "ENOENT")
|
|
62
|
-
|
|
65
|
+
if (e.code === "ENOENT") {
|
|
66
|
+
const names = workspaceTargets(root());
|
|
67
|
+
throw new Error(names.length
|
|
68
|
+
? `No target "${name}" in this workspace. It has: ${names.join(", ")}. Pass --target <name> or set UC_TARGET.`
|
|
69
|
+
: `No target "${name}" in this workspace. Run: uc-config connect ${name} --host http://<REMOTE_IP>`);
|
|
70
|
+
}
|
|
63
71
|
throw e;
|
|
64
72
|
}
|
|
65
73
|
let token = process.env[target.tokenEnv];
|
|
@@ -147,7 +155,7 @@ async function connectTarget(name, host, tokenEnv = "UC_API_KEY") {
|
|
|
147
155
|
try {
|
|
148
156
|
const old = await readJson(targetFile(name));
|
|
149
157
|
if (old.identity !== target.identity)
|
|
150
|
-
throw new Error("
|
|
158
|
+
throw new Error("This folder is already connected to a different remote. Use one folder per remote (mkdir ../other-remote && cd ../other-remote && npx uc-config init).");
|
|
151
159
|
}
|
|
152
160
|
catch (e) {
|
|
153
161
|
if (e.code !== "ENOENT")
|
|
@@ -194,6 +202,31 @@ async function authenticate(name, pin) {
|
|
|
194
202
|
console.log("API key saved in .uc/credentials.json (mode 0600, gitignored). Approve it on the remote if requested, then run doctor.");
|
|
195
203
|
}
|
|
196
204
|
}
|
|
205
|
+
/** Latest published version, or undefined if offline/disabled. Never throws. */
|
|
206
|
+
async function latestVersion() {
|
|
207
|
+
if (process.env.UC_NO_UPDATE_CHECK)
|
|
208
|
+
return undefined;
|
|
209
|
+
try {
|
|
210
|
+
const res = await fetch("https://registry.npmjs.org/uc-config/latest", {
|
|
211
|
+
signal: AbortSignal.timeout(3000),
|
|
212
|
+
});
|
|
213
|
+
if (!res.ok)
|
|
214
|
+
return undefined;
|
|
215
|
+
const v = (await res.json()).version;
|
|
216
|
+
return typeof v === "string" ? v : undefined;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function newer(a, b) {
|
|
223
|
+
const p = (v) => v.split("-")[0].split(".").map(Number);
|
|
224
|
+
const [x, y] = [p(a), p(b)];
|
|
225
|
+
for (let i = 0; i < 3; i++)
|
|
226
|
+
if ((x[i] ?? 0) !== (y[i] ?? 0))
|
|
227
|
+
return (x[i] ?? 0) > (y[i] ?? 0);
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
197
230
|
async function question(label) {
|
|
198
231
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
199
232
|
try {
|
|
@@ -210,6 +243,9 @@ program
|
|
|
210
243
|
const { client, target } = await load(o.target);
|
|
211
244
|
await client.verifyTarget(target);
|
|
212
245
|
console.log(`Identity verified; core ${target.version.core}, reported API ${target.version.api}`);
|
|
246
|
+
const latest = await latestVersion();
|
|
247
|
+
if (latest && newer(latest, pkgVersion))
|
|
248
|
+
console.log(`Update available: uc-config ${pkgVersion} -> ${latest}. Run: npm install uc-config@latest && npx uc-config init --refresh-docs (see CHANGELOG.md)`);
|
|
213
249
|
for (const path of [
|
|
214
250
|
"/entities",
|
|
215
251
|
"/activities",
|
|
@@ -537,26 +573,45 @@ program
|
|
|
537
573
|
.command("init")
|
|
538
574
|
.description("Scaffold a private config workspace (package.json, tsconfig, .gitignore, AGENTS.md)")
|
|
539
575
|
.option("--host <ip>", "remote IP address (skips the prompt)")
|
|
540
|
-
.option("--target <name>", "target name
|
|
576
|
+
.option("--target <name>", "target name (default: the folder's existing target, else home)")
|
|
541
577
|
.option("--no-connect", "only create files; don't connect or authenticate")
|
|
578
|
+
.option("--refresh-docs", "update AGENTS.md/CLAUDE.md to this version (edited files get a .new copy)")
|
|
542
579
|
.action(async (o) => {
|
|
543
|
-
const r = await init(root(), pkgVersion);
|
|
580
|
+
const r = await init(root(), pkgVersion, { refreshDocs: o.refreshDocs });
|
|
544
581
|
for (const f of r.written)
|
|
545
582
|
console.log(`created ${f}`);
|
|
546
583
|
if (r.packageJsonUpdated)
|
|
547
584
|
console.log("added uc-config to package.json");
|
|
585
|
+
for (const f of r.refreshed)
|
|
586
|
+
console.log(`updated ${f} to v${pkgVersion}`);
|
|
587
|
+
for (const f of r.conflicts)
|
|
588
|
+
console.log(`kept ${f} (edited); wrote ${f}.new. Merge your changes, then delete ${f}.new`);
|
|
548
589
|
for (const f of r.skipped)
|
|
549
590
|
console.log(`kept existing ${f}`);
|
|
591
|
+
if (o.refreshDocs) {
|
|
592
|
+
if (r.conflicts.length)
|
|
593
|
+
process.exitCode = 2;
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
550
596
|
const interactive = Boolean(process.stdin.isTTY);
|
|
551
|
-
const next =
|
|
597
|
+
const next = 'Next: npm install, then start your coding agent here and ask it to "Set up my Remote 3".';
|
|
552
598
|
if (!o.connect)
|
|
553
599
|
return console.log(next);
|
|
554
|
-
const
|
|
600
|
+
const existing = workspaceTargets(root());
|
|
601
|
+
const name = o.target ?? (existing.length === 1 ? existing[0] : "home");
|
|
602
|
+
if (existing.length && !existing.includes(name)) {
|
|
603
|
+
console.log(`This folder already manages ${existing.join(", ")}. Use one folder per remote:\n` +
|
|
604
|
+
" mkdir ../other-remote && cd ../other-remote && npx uc-config init");
|
|
605
|
+
process.exitCode = 1;
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
555
608
|
// 1. Connect (unless already connected).
|
|
556
609
|
let target;
|
|
557
610
|
try {
|
|
558
611
|
target = await readJson(targetFile(name));
|
|
559
612
|
console.log(`Already connected to ${target.host} as "${name}".`);
|
|
613
|
+
if (o.host)
|
|
614
|
+
console.log(`Ignoring --host: this folder already manages "${name}". For another remote, use a new folder.`);
|
|
560
615
|
}
|
|
561
616
|
catch (e) {
|
|
562
617
|
if (e.code !== "ENOENT")
|
package/dist/init.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
/** True when the file is unedited generated output from any uc-config version. */
|
|
2
|
+
export declare function isPristine(content: string): boolean;
|
|
1
3
|
export interface InitResult {
|
|
2
4
|
written: string[];
|
|
3
5
|
skipped: string[];
|
|
4
6
|
packageJsonUpdated: boolean;
|
|
7
|
+
/** Generated docs replaced by --refresh-docs. */
|
|
8
|
+
refreshed: string[];
|
|
9
|
+
/** Edited docs kept; the new version was written to `<name>.new`. */
|
|
10
|
+
conflicts: string[];
|
|
5
11
|
}
|
|
6
12
|
/** Scaffold a private config workspace. Never overwrites existing files. */
|
|
7
|
-
export declare function init(dir: string, version: string
|
|
13
|
+
export declare function init(dir: string, version: string, options?: {
|
|
14
|
+
refreshDocs?: boolean;
|
|
15
|
+
}): Promise<InitResult>;
|
package/dist/init.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
const sha256 = (s) => createHash("sha256").update(s).digest("hex");
|
|
5
|
+
const MARKER = /^<!-- uc-config:generated v(\S+) sha256:([0-9a-f]{64}) -->\n/;
|
|
6
|
+
/** Prefix generated docs with a marker so --refresh-docs can detect edits. */
|
|
7
|
+
const stamp = (version, body) => `<!-- uc-config:generated v${version} sha256:${sha256(body)} -->\n${body}`;
|
|
8
|
+
/** Exact output of releases that predate the marker (0.1.0, 0.2.0). */
|
|
9
|
+
const LEGACY = new Set([
|
|
10
|
+
"053dd83c530adb91f58ad52148c9d858cc28864a137b7b5e65c4563338e91b4f",
|
|
11
|
+
"159e847a6a5b6c5cb9ed96f400e8f5d58cd9acae2e68bf666fc3fae2e4ad249b",
|
|
12
|
+
"d71e02c349b769c916d166a6b26cc14d80da4142042fa90564bda85c897a9b07",
|
|
13
|
+
]);
|
|
14
|
+
/** True when the file is unedited generated output from any uc-config version. */
|
|
15
|
+
export function isPristine(content) {
|
|
16
|
+
const m = MARKER.exec(content);
|
|
17
|
+
if (m)
|
|
18
|
+
return sha256(content.slice(m[0].length)) === m[2];
|
|
19
|
+
return LEGACY.has(sha256(content));
|
|
20
|
+
}
|
|
3
21
|
const agents = (version) => `# Remote 3 configuration (uc-config)
|
|
4
22
|
|
|
5
23
|
This folder holds the user's Unfolded Circle Remote 3 configuration. It is
|
|
@@ -53,10 +71,28 @@ Re-adding a dropped entity the integration still offers is safe to do
|
|
|
53
71
|
directly. Ask before anything else. Integration installs and updates belong to
|
|
54
72
|
the UC Integration Manager (http://<remote>:9999); run diagnose after any update.
|
|
55
73
|
|
|
74
|
+
## Multiple remotes
|
|
75
|
+
|
|
76
|
+
This folder manages exactly one remote (one target in \`.uc/targets/\`). For
|
|
77
|
+
another remote, create a sibling folder and run \`npx uc-config init\` there.
|
|
78
|
+
Never connect a second remote here, and never copy \`.uc/\` between folders.
|
|
79
|
+
Shared pieces can be imported from a common .ts file, but entity IDs must come
|
|
80
|
+
from each folder's own generated/devices.ts.
|
|
81
|
+
|
|
82
|
+
## If the remote doesn't respond
|
|
83
|
+
|
|
84
|
+
\`transport failed\` or timeouts usually mean the remote went to sleep. Ask the
|
|
85
|
+
user to pick it up or dock it, then retry. Don't change the host.
|
|
86
|
+
|
|
56
87
|
## Upgrading the tool
|
|
57
88
|
|
|
58
|
-
\`npm
|
|
59
|
-
|
|
89
|
+
1. \`npm install uc-config@latest\` (not \`npm update\`: it won't cross 0.x minor versions).
|
|
90
|
+
2. \`npx uc-config init --refresh-docs\` to update this file and CLAUDE.md.
|
|
91
|
+
Files the user edited are kept; the new version is written beside them as \`.new\`.
|
|
92
|
+
3. Read node_modules/uc-config/CHANGELOG.md for any "Action required" notes.
|
|
93
|
+
4. \`npx uc-config compile && npx uc-config plan\`. It must show 0 operations
|
|
94
|
+
before you make any other change. If not, the upgrade changed how the config
|
|
95
|
+
is read: show the user the plan and don't apply it.
|
|
60
96
|
`;
|
|
61
97
|
// Claude Code reads CLAUDE.md, not AGENTS.md. Newer releases follow the
|
|
62
98
|
// @-import; the prose line covers releases that don't support imports.
|
|
@@ -85,12 +121,36 @@ const gitignore = `node_modules/
|
|
|
85
121
|
.env.*
|
|
86
122
|
`;
|
|
87
123
|
/** Scaffold a private config workspace. Never overwrites existing files. */
|
|
88
|
-
export async function init(dir, version) {
|
|
124
|
+
export async function init(dir, version, options = {}) {
|
|
89
125
|
await mkdir(dir, { recursive: true });
|
|
90
126
|
const result = {
|
|
91
127
|
written: [],
|
|
92
128
|
skipped: [],
|
|
93
129
|
packageJsonUpdated: false,
|
|
130
|
+
refreshed: [],
|
|
131
|
+
conflicts: [],
|
|
132
|
+
};
|
|
133
|
+
const doc = async (name, contents) => {
|
|
134
|
+
let existing;
|
|
135
|
+
try {
|
|
136
|
+
existing = await readFile(join(dir, name), "utf8");
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
if (e.code !== "ENOENT")
|
|
140
|
+
throw e;
|
|
141
|
+
}
|
|
142
|
+
if (existing === undefined)
|
|
143
|
+
return put(name, contents);
|
|
144
|
+
if (!options.refreshDocs || existing === contents)
|
|
145
|
+
return void result.skipped.push(name);
|
|
146
|
+
if (isPristine(existing)) {
|
|
147
|
+
await writeFile(join(dir, name), contents);
|
|
148
|
+
result.refreshed.push(name);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
await writeFile(join(dir, `${name}.new`), contents);
|
|
152
|
+
result.conflicts.push(name);
|
|
153
|
+
}
|
|
94
154
|
};
|
|
95
155
|
const put = async (name, contents) => {
|
|
96
156
|
try {
|
|
@@ -134,7 +194,7 @@ export async function init(dir, version) {
|
|
|
134
194
|
}
|
|
135
195
|
await put("tsconfig.json", JSON.stringify(tsconfig, null, 2) + "\n");
|
|
136
196
|
await put(".gitignore", gitignore);
|
|
137
|
-
await
|
|
138
|
-
await
|
|
197
|
+
await doc("AGENTS.md", stamp(version, agents(version)));
|
|
198
|
+
await doc("CLAUDE.md", stamp(version, claude));
|
|
139
199
|
return result;
|
|
140
200
|
}
|
package/docs/cli.md
CHANGED
|
@@ -12,6 +12,7 @@ the workspace's only target if exactly one is connected; otherwise `home`.
|
|
|
12
12
|
| Command | Writes to remote | Purpose |
|
|
13
13
|
| ---------------------------------------------- | ----------------- | ------------------------------------------------------------------------------ |
|
|
14
14
|
| `init [--host ip] [--no-connect]` | API key only | Scaffold a workspace, then prompt for IP and PIN (connect + auth). Rerunnable. |
|
|
15
|
+
| `init --refresh-docs` | no | Update AGENTS.md/CLAUDE.md; edited files are kept and get a `.new` copy. |
|
|
15
16
|
| `connect <name> --host <url>` | no | Record a target (identity, firmware). Rerun after firmware updates. |
|
|
16
17
|
| `auth` | API key only | Exchange the web-configurator PIN (`UC_PIN` or prompt) for an API key. |
|
|
17
18
|
| `doctor` | no | Verify identity and read access to every required endpoint. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uc-config",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Configuration-as-code for the Unfolded Circle Remote 3, designed to be driven by coding agents",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"examples",
|
|
37
37
|
"remote.config.example.ts",
|
|
38
38
|
"README.md",
|
|
39
|
+
"CHANGELOG.md",
|
|
39
40
|
"LICENSE"
|
|
40
41
|
],
|
|
41
42
|
"engines": {
|