uc-config 0.1.0
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/LICENSE +24 -0
- package/README.md +229 -0
- package/dist/adapter.d.ts +26 -0
- package/dist/adapter.js +540 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +555 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.js +182 -0
- package/dist/compiler.d.ts +5 -0
- package/dist/compiler.js +155 -0
- package/dist/diagnose.d.ts +41 -0
- package/dist/diagnose.js +133 -0
- package/dist/dsl.d.ts +67 -0
- package/dist/dsl.js +103 -0
- package/dist/engine.d.ts +32 -0
- package/dist/engine.js +276 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/init.d.ts +7 -0
- package/dist/init.js +124 -0
- package/dist/inventory.d.ts +14 -0
- package/dist/inventory.js +236 -0
- package/dist/model.d.ts +91 -0
- package/dist/model.js +7 -0
- package/dist/planner.d.ts +12 -0
- package/dist/planner.js +248 -0
- package/dist/recovery.d.ts +4 -0
- package/dist/recovery.js +63 -0
- package/dist/schema.d.ts +4 -0
- package/dist/schema.js +75 -0
- package/dist/transport.d.ts +2 -0
- package/dist/transport.js +101 -0
- package/dist/util.d.ts +18 -0
- package/dist/util.js +140 -0
- package/dist/wire.d.ts +17199 -0
- package/docs/cli.md +125 -0
- package/docs/configuration-authoring.md +196 -0
- package/docs/handoff.md +24 -0
- package/docs/snippets.md +312 -0
- package/examples/full-setup.ts +113 -0
- package/package.json +67 -0
- package/remote.config.example.ts +65 -0
- package/vendor/README.md +9 -0
- package/vendor/core-api.json +1 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
activity,
|
|
3
|
+
bind,
|
|
4
|
+
button,
|
|
5
|
+
command,
|
|
6
|
+
defineRemote,
|
|
7
|
+
delay,
|
|
8
|
+
dock,
|
|
9
|
+
driver,
|
|
10
|
+
entity,
|
|
11
|
+
integration,
|
|
12
|
+
irCode,
|
|
13
|
+
localCommand,
|
|
14
|
+
macro,
|
|
15
|
+
page,
|
|
16
|
+
pairing,
|
|
17
|
+
profile,
|
|
18
|
+
ref,
|
|
19
|
+
remote,
|
|
20
|
+
resource,
|
|
21
|
+
secret,
|
|
22
|
+
settings,
|
|
23
|
+
} from "uc-config";
|
|
24
|
+
|
|
25
|
+
// Template only: replace hostnames, driver IDs, entity IDs and commands from inventory.
|
|
26
|
+
// Provisioning and dependent configuration are separate plan/apply phases.
|
|
27
|
+
const volume = command(ref("receiver"), "REPLACE_WITH_VOLUME_COMMAND");
|
|
28
|
+
|
|
29
|
+
export default defineRemote({
|
|
30
|
+
schemaVersion: 1,
|
|
31
|
+
resources: {
|
|
32
|
+
device: settings("device", { name: "Living room" }),
|
|
33
|
+
mediaDriver: driver("my-media-driver", {
|
|
34
|
+
driver_url: "ws://media-driver.local:9090",
|
|
35
|
+
}),
|
|
36
|
+
media: integration({
|
|
37
|
+
driver: ref("mediaDriver"),
|
|
38
|
+
name: "Living room devices",
|
|
39
|
+
// Inputs must match the selected driver's setup_data_schema.
|
|
40
|
+
setup: { host: "receiver.local", token: secret("env:MEDIA_TOKEN", "v1") },
|
|
41
|
+
}),
|
|
42
|
+
receiver: entity({
|
|
43
|
+
integration: ref("media"),
|
|
44
|
+
entityId: "REPLACE_WITH_AVAILABLE_ENTITY_ID",
|
|
45
|
+
}),
|
|
46
|
+
chargingDock: dock({
|
|
47
|
+
setup: {
|
|
48
|
+
manually: {
|
|
49
|
+
name: "Living room dock",
|
|
50
|
+
custom_ws_url: "dock.local",
|
|
51
|
+
token: secret("env:DOCK_TOKEN"),
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
data: { name: "Living room dock" },
|
|
55
|
+
}),
|
|
56
|
+
television: remote({
|
|
57
|
+
create: {
|
|
58
|
+
name: { en: "TV" },
|
|
59
|
+
custom_codeset: { manufacturer_id: "custom", device_name: "TV" },
|
|
60
|
+
},
|
|
61
|
+
data: { name: { en: "TV" } },
|
|
62
|
+
}),
|
|
63
|
+
// Use a learned/exported real code before applying this resource.
|
|
64
|
+
tvPower: irCode(ref("television"), "POWER", {
|
|
65
|
+
format: "PRONTO",
|
|
66
|
+
value: "REPLACE_WITH_LEARNED_CODE",
|
|
67
|
+
}),
|
|
68
|
+
streamer: remote({
|
|
69
|
+
create: { name: { en: "Streamer" }, kind: "BT", bt: {} },
|
|
70
|
+
data: { name: { en: "Streamer" } },
|
|
71
|
+
}),
|
|
72
|
+
streamerPairing: pairing(ref("streamer")),
|
|
73
|
+
streamerHome: bind(
|
|
74
|
+
ref("streamer"),
|
|
75
|
+
"HOME",
|
|
76
|
+
localCommand("HOME"),
|
|
77
|
+
"short_press",
|
|
78
|
+
"remote",
|
|
79
|
+
),
|
|
80
|
+
watchTV: activity({
|
|
81
|
+
name: "Watch TV",
|
|
82
|
+
entities: [ref("television"), ref("receiver"), ref("streamer")],
|
|
83
|
+
on: [command(ref("television"), "POWER"), delay(1500)],
|
|
84
|
+
options: { prevent_sleep: false },
|
|
85
|
+
}),
|
|
86
|
+
volumeUp: bind(ref("watchTV"), "VOLUME_UP", volume),
|
|
87
|
+
controls: page(ref("watchTV"), {
|
|
88
|
+
name: "Controls",
|
|
89
|
+
grid: { width: 4, height: 6 },
|
|
90
|
+
items: [
|
|
91
|
+
button({
|
|
92
|
+
label: "Home",
|
|
93
|
+
at: [0, 0],
|
|
94
|
+
size: [2, 1],
|
|
95
|
+
command: command(ref("streamer"), "HOME"),
|
|
96
|
+
}),
|
|
97
|
+
],
|
|
98
|
+
}),
|
|
99
|
+
mute: macro({
|
|
100
|
+
name: "Mute",
|
|
101
|
+
entities: [ref("receiver")],
|
|
102
|
+
steps: [command(ref("receiver"), "REPLACE_WITH_MUTE_COMMAND")],
|
|
103
|
+
}),
|
|
104
|
+
family: profile({ name: "Family", restricted: false }),
|
|
105
|
+
home: resource("profilePage", {
|
|
106
|
+
parent: ref("family"),
|
|
107
|
+
data: {
|
|
108
|
+
name: "Home",
|
|
109
|
+
items: [{ entity_id: ref("watchTV") }, { entity_id: ref("mute") }],
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "uc-config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Configuration-as-code for the Unfolded Circle Remote 3, designed to be driven by coding agents",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/bpolly/uc-config#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/bpolly/uc-config/issues"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/bpolly/uc-config.git"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"unfolded-circle",
|
|
17
|
+
"remote-3",
|
|
18
|
+
"home-theater",
|
|
19
|
+
"configuration-as-code",
|
|
20
|
+
"infrastructure-as-code",
|
|
21
|
+
"ai-agents"
|
|
22
|
+
],
|
|
23
|
+
"bin": {
|
|
24
|
+
"uc-config": "dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"vendor",
|
|
35
|
+
"docs",
|
|
36
|
+
"examples",
|
|
37
|
+
"remote.config.example.ts",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc && node scripts/copy-types.mjs",
|
|
46
|
+
"check": "tsc --noEmit",
|
|
47
|
+
"test": "npm run build --silent && tsx --test test/*.test.ts",
|
|
48
|
+
"uc": "tsx src/cli.ts",
|
|
49
|
+
"generate": "openapi-typescript vendor/core-api.json -o src/wire.d.ts",
|
|
50
|
+
"format": "prettier --write src/*.ts test/*.ts examples/*.ts remote.config.example.ts README.md docs/*.md",
|
|
51
|
+
"format:check": "prettier --check src/*.ts test/*.ts examples/*.ts remote.config.example.ts README.md docs/*.md",
|
|
52
|
+
"check:examples": "tsc -p tsconfig.examples.json",
|
|
53
|
+
"prepublishOnly": "npm run check && npm test && npm run check:examples"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"ajv": "^8.20.0",
|
|
57
|
+
"ajv-formats": "^3.0.1",
|
|
58
|
+
"commander": "^15.0.0",
|
|
59
|
+
"tsx": "^4.23.13"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^26.6.2",
|
|
63
|
+
"openapi-typescript": "^7.13.0",
|
|
64
|
+
"prettier": "^3.9.8",
|
|
65
|
+
"typescript": "^5.9.3"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Starter configuration. For an existing remote, prefer generating
|
|
2
|
+
// remote.config.ts with `npm run uc -- import` instead of copying this file.
|
|
3
|
+
//
|
|
4
|
+
// Every entity ID and command below is a placeholder. Replace them with exact
|
|
5
|
+
// values from generated/devices.ts (written by `inventory --bindings`).
|
|
6
|
+
import {
|
|
7
|
+
activity,
|
|
8
|
+
bind,
|
|
9
|
+
button,
|
|
10
|
+
command,
|
|
11
|
+
defineRemote,
|
|
12
|
+
delay,
|
|
13
|
+
page,
|
|
14
|
+
ref,
|
|
15
|
+
} from "uc-config";
|
|
16
|
+
|
|
17
|
+
const tv = "REPLACE.main.media_player.TV_ID";
|
|
18
|
+
const receiver = "REPLACE.main.media_player.RECEIVER_ID";
|
|
19
|
+
const streamer = "REPLACE.main.media_player.STREAMER_ID";
|
|
20
|
+
|
|
21
|
+
export default defineRemote({
|
|
22
|
+
schemaVersion: 1,
|
|
23
|
+
resources: {
|
|
24
|
+
"activity.watch_tv": activity({
|
|
25
|
+
name: "Watch TV",
|
|
26
|
+
entities: [tv, receiver, streamer],
|
|
27
|
+
on: [
|
|
28
|
+
command(tv, "media_player.on"),
|
|
29
|
+
delay(1500),
|
|
30
|
+
command(receiver, "media_player.on"),
|
|
31
|
+
],
|
|
32
|
+
off: [
|
|
33
|
+
command(receiver, "media_player.off"),
|
|
34
|
+
command(tv, "media_player.off"),
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
"activity.watch_tv.button.volume_up": bind(
|
|
38
|
+
ref("activity.watch_tv"),
|
|
39
|
+
"VOLUME_UP",
|
|
40
|
+
command(receiver, "media_player.volume_up"),
|
|
41
|
+
),
|
|
42
|
+
"activity.watch_tv.button.volume_down": bind(
|
|
43
|
+
ref("activity.watch_tv"),
|
|
44
|
+
"VOLUME_DOWN",
|
|
45
|
+
command(receiver, "media_player.volume_down"),
|
|
46
|
+
),
|
|
47
|
+
"activity.watch_tv.button.home": bind(
|
|
48
|
+
ref("activity.watch_tv"),
|
|
49
|
+
"HOME",
|
|
50
|
+
command(streamer, "media_player.home"),
|
|
51
|
+
),
|
|
52
|
+
"activity.watch_tv.page.main": page(ref("activity.watch_tv"), {
|
|
53
|
+
name: "Main",
|
|
54
|
+
grid: { width: 4, height: 6 },
|
|
55
|
+
items: [
|
|
56
|
+
button({
|
|
57
|
+
label: "Play / Pause",
|
|
58
|
+
at: [0, 0],
|
|
59
|
+
size: [2, 1],
|
|
60
|
+
command: command(streamer, "media_player.play_pause"),
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
}),
|
|
64
|
+
},
|
|
65
|
+
});
|
package/vendor/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Upstream specification
|
|
2
|
+
|
|
3
|
+
`core-api.json` is a YAML-to-JSON conversion (no semantic changes) of
|
|
4
|
+
https://github.com/unfoldedcircle/core-api/blob/04b0d08ccc59f3f146aa9ad031d0c87a0502fce7/core-api/rest/UCR-core-openapi.yaml
|
|
5
|
+
|
|
6
|
+
Copyright Unfolded Circle and contributors. Specification licensed CC-BY-SA-4.0:
|
|
7
|
+
https://creativecommons.org/licenses/by-sa/4.0/
|
|
8
|
+
|
|
9
|
+
Specification version: 0.46.0. This is not the same version identifier as the device's public `api` field. Generated wire types are derived from this specification. Hardware compatibility must be checked separately.
|