@camstack/system 1.2.344 → 1.2.345

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.
@@ -0,0 +1,110 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ require("../../chunk-Cek0wNdY.js");
6
+ const require_dist = require("../../dist-CqafgUSr.js");
7
+ const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
+ //#region src/builtins/calendars/calendars.addon.ts
9
+ /**
10
+ * Hub calendars aggregator — walks `calendar-source` providers and stamps
11
+ * cluster-stable ids (`<providerAddonId>:<localId>`).
12
+ */
13
+ var PER_SOURCE_TIMEOUT_MS = 2500;
14
+ var HA_ADDON_ID = "provider-homeassistant";
15
+ function stampId(providerAddonId, localId) {
16
+ return `${providerAddonId}:${localId}`;
17
+ }
18
+ function localIdOf(stamped, providerAddonId) {
19
+ const prefix = `${providerAddonId}:`;
20
+ if (!stamped.startsWith(prefix)) return null;
21
+ return stamped.slice(prefix.length);
22
+ }
23
+ var CalendarsAddon = class extends require_dist.BaseAddon {
24
+ id = "calendars";
25
+ constructor() {
26
+ super({});
27
+ }
28
+ async onInitialize() {
29
+ const provider = {
30
+ listCalendars: async () => this.listCalendars(),
31
+ listEvents: async (input) => this.listEvents(input),
32
+ importFromHomeAssistant: async () => this.importFromHomeAssistant()
33
+ };
34
+ this.ctx.logger.info("Initialized — aggregating calendar-source providers");
35
+ return [{
36
+ capability: require_dist.calendarsCapability,
37
+ provider
38
+ }];
39
+ }
40
+ sources() {
41
+ return (this.capabilities?.getCollectionEntries("calendar-source") ?? []).map(([id, provider]) => ({
42
+ id,
43
+ provider
44
+ }));
45
+ }
46
+ async listCalendars() {
47
+ const settled = await require_settle_sources.settleSourcesWithTimeout(this.sources().map((s) => [s.id, async () => {
48
+ return (await s.provider.listCalendars()).map((cal) => ({
49
+ ...cal,
50
+ id: stampId(s.id, cal.id),
51
+ providerAddonId: s.id
52
+ }));
53
+ }]), PER_SOURCE_TIMEOUT_MS);
54
+ const out = [];
55
+ for (const [sourceId, result] of settled) if (result.ok) for (const entry of result.value) out.push(entry);
56
+ else this.ctx.logger.warn("calendar-source provider failed", { meta: {
57
+ sourceId,
58
+ error: result.error.message
59
+ } });
60
+ return out;
61
+ }
62
+ async listEvents(input) {
63
+ const sources = this.sources();
64
+ const wanted = input.calendarIds !== void 0 ? new Set(input.calendarIds) : null;
65
+ const settled = await require_settle_sources.settleSourcesWithTimeout(sources.map((s) => {
66
+ const localIds = wanted === null ? void 0 : [...wanted].map((id) => localIdOf(id, s.id)).filter((id) => id !== null);
67
+ return [s.id, async () => {
68
+ if (wanted !== null && localIds !== void 0 && localIds.length === 0) return [];
69
+ return (await s.provider.listEvents({
70
+ startMs: input.startMs,
71
+ endMs: input.endMs,
72
+ ...localIds !== void 0 ? { calendarIds: [...localIds] } : {}
73
+ })).map((ev) => ({
74
+ ...ev,
75
+ calendarId: stampId(s.id, ev.calendarId),
76
+ id: stampId(s.id, ev.id)
77
+ }));
78
+ }];
79
+ }), PER_SOURCE_TIMEOUT_MS);
80
+ const out = [];
81
+ for (const [sourceId, result] of settled) if (result.ok) for (const ev of result.value) out.push(ev);
82
+ else this.ctx.logger.warn("calendar-source listEvents failed", { meta: {
83
+ sourceId,
84
+ error: result.error.message
85
+ } });
86
+ return out.toSorted((a, b) => a.startMs - b.startMs);
87
+ }
88
+ async importFromHomeAssistant() {
89
+ const ha = this.sources().find((s) => s.id === HA_ADDON_ID || s.id.includes("homeassistant"));
90
+ if (ha === void 0) return {
91
+ imported: 0,
92
+ error: "No Home Assistant calendar-source provider is registered"
93
+ };
94
+ try {
95
+ return {
96
+ imported: (await ha.provider.listCalendars()).length,
97
+ providerAddonId: ha.id
98
+ };
99
+ } catch (err) {
100
+ return {
101
+ imported: 0,
102
+ providerAddonId: ha.id,
103
+ error: require_dist.errMsg(err)
104
+ };
105
+ }
106
+ }
107
+ };
108
+ //#endregion
109
+ exports.CalendarsAddon = CalendarsAddon;
110
+ exports.default = CalendarsAddon;
@@ -0,0 +1,104 @@
1
+ import { Gn as BaseAddon, Wn as errMsg, Z as calendarsCapability } from "../../dist-0zO6jHkf.mjs";
2
+ import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
+ //#region src/builtins/calendars/calendars.addon.ts
4
+ /**
5
+ * Hub calendars aggregator — walks `calendar-source` providers and stamps
6
+ * cluster-stable ids (`<providerAddonId>:<localId>`).
7
+ */
8
+ var PER_SOURCE_TIMEOUT_MS = 2500;
9
+ var HA_ADDON_ID = "provider-homeassistant";
10
+ function stampId(providerAddonId, localId) {
11
+ return `${providerAddonId}:${localId}`;
12
+ }
13
+ function localIdOf(stamped, providerAddonId) {
14
+ const prefix = `${providerAddonId}:`;
15
+ if (!stamped.startsWith(prefix)) return null;
16
+ return stamped.slice(prefix.length);
17
+ }
18
+ var CalendarsAddon = class extends BaseAddon {
19
+ id = "calendars";
20
+ constructor() {
21
+ super({});
22
+ }
23
+ async onInitialize() {
24
+ const provider = {
25
+ listCalendars: async () => this.listCalendars(),
26
+ listEvents: async (input) => this.listEvents(input),
27
+ importFromHomeAssistant: async () => this.importFromHomeAssistant()
28
+ };
29
+ this.ctx.logger.info("Initialized — aggregating calendar-source providers");
30
+ return [{
31
+ capability: calendarsCapability,
32
+ provider
33
+ }];
34
+ }
35
+ sources() {
36
+ return (this.capabilities?.getCollectionEntries("calendar-source") ?? []).map(([id, provider]) => ({
37
+ id,
38
+ provider
39
+ }));
40
+ }
41
+ async listCalendars() {
42
+ const settled = await settleSourcesWithTimeout(this.sources().map((s) => [s.id, async () => {
43
+ return (await s.provider.listCalendars()).map((cal) => ({
44
+ ...cal,
45
+ id: stampId(s.id, cal.id),
46
+ providerAddonId: s.id
47
+ }));
48
+ }]), PER_SOURCE_TIMEOUT_MS);
49
+ const out = [];
50
+ for (const [sourceId, result] of settled) if (result.ok) for (const entry of result.value) out.push(entry);
51
+ else this.ctx.logger.warn("calendar-source provider failed", { meta: {
52
+ sourceId,
53
+ error: result.error.message
54
+ } });
55
+ return out;
56
+ }
57
+ async listEvents(input) {
58
+ const sources = this.sources();
59
+ const wanted = input.calendarIds !== void 0 ? new Set(input.calendarIds) : null;
60
+ const settled = await settleSourcesWithTimeout(sources.map((s) => {
61
+ const localIds = wanted === null ? void 0 : [...wanted].map((id) => localIdOf(id, s.id)).filter((id) => id !== null);
62
+ return [s.id, async () => {
63
+ if (wanted !== null && localIds !== void 0 && localIds.length === 0) return [];
64
+ return (await s.provider.listEvents({
65
+ startMs: input.startMs,
66
+ endMs: input.endMs,
67
+ ...localIds !== void 0 ? { calendarIds: [...localIds] } : {}
68
+ })).map((ev) => ({
69
+ ...ev,
70
+ calendarId: stampId(s.id, ev.calendarId),
71
+ id: stampId(s.id, ev.id)
72
+ }));
73
+ }];
74
+ }), PER_SOURCE_TIMEOUT_MS);
75
+ const out = [];
76
+ for (const [sourceId, result] of settled) if (result.ok) for (const ev of result.value) out.push(ev);
77
+ else this.ctx.logger.warn("calendar-source listEvents failed", { meta: {
78
+ sourceId,
79
+ error: result.error.message
80
+ } });
81
+ return out.toSorted((a, b) => a.startMs - b.startMs);
82
+ }
83
+ async importFromHomeAssistant() {
84
+ const ha = this.sources().find((s) => s.id === HA_ADDON_ID || s.id.includes("homeassistant"));
85
+ if (ha === void 0) return {
86
+ imported: 0,
87
+ error: "No Home Assistant calendar-source provider is registered"
88
+ };
89
+ try {
90
+ return {
91
+ imported: (await ha.provider.listCalendars()).length,
92
+ providerAddonId: ha.id
93
+ };
94
+ } catch (err) {
95
+ return {
96
+ imported: 0,
97
+ providerAddonId: ha.id,
98
+ error: errMsg(err)
99
+ };
100
+ }
101
+ }
102
+ };
103
+ //#endregion
104
+ export { CalendarsAddon, CalendarsAddon as default };
@@ -0,0 +1,8 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ require("../../chunk-Cek0wNdY.js");
6
+ const require_builtins_calendars_calendars_addon = require("./calendars.addon.js");
7
+ exports.CalendarsAddon = require_builtins_calendars_calendars_addon.CalendarsAddon;
8
+ exports.default = require_builtins_calendars_calendars_addon.CalendarsAddon;
@@ -0,0 +1,2 @@
1
+ import { CalendarsAddon } from "./calendars.addon.mjs";
2
+ export { CalendarsAddon, CalendarsAddon as default };
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@ const require_chunk = require("./chunk-Cek0wNdY.js");
3
3
  const require_dist = require("./dist-CqafgUSr.js");
4
4
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
5
5
  require("./builtins/alerts/index.js");
6
- const require_settle_sources = require("./settle-sources-Bhsy57y-.js");
6
+ const require_builtins_calendars_calendars_addon = require("./builtins/calendars/calendars.addon.js");
7
+ require("./builtins/calendars/index.js");
7
8
  const require_builtins_composer_composer_addon = require("./builtins/composer/composer.addon.js");
8
9
  require("./builtins/composer/index.js");
9
10
  const require_formatter = require("./formatter-DqAKDlvN.js");
@@ -186,107 +187,6 @@ function matchPath(pattern, path) {
186
187
  return params;
187
188
  }
188
189
  //#endregion
189
- //#region src/builtins/calendars/calendars.addon.ts
190
- /**
191
- * Hub calendars aggregator — walks `calendar-source` providers and stamps
192
- * cluster-stable ids (`<providerAddonId>:<localId>`).
193
- */
194
- var PER_SOURCE_TIMEOUT_MS = 2500;
195
- var HA_ADDON_ID = "provider-homeassistant";
196
- function stampId(providerAddonId, localId) {
197
- return `${providerAddonId}:${localId}`;
198
- }
199
- function localIdOf(stamped, providerAddonId) {
200
- const prefix = `${providerAddonId}:`;
201
- if (!stamped.startsWith(prefix)) return null;
202
- return stamped.slice(prefix.length);
203
- }
204
- var CalendarsAddon = class extends require_dist.BaseAddon {
205
- id = "calendars";
206
- constructor() {
207
- super({});
208
- }
209
- async onInitialize() {
210
- const provider = {
211
- listCalendars: async () => this.listCalendars(),
212
- listEvents: async (input) => this.listEvents(input),
213
- importFromHomeAssistant: async () => this.importFromHomeAssistant()
214
- };
215
- this.ctx.logger.info("Initialized — aggregating calendar-source providers");
216
- return [{
217
- capability: require_dist.calendarsCapability,
218
- provider
219
- }];
220
- }
221
- sources() {
222
- return (this.capabilities?.getCollectionEntries("calendar-source") ?? []).map(([id, provider]) => ({
223
- id,
224
- provider
225
- }));
226
- }
227
- async listCalendars() {
228
- const settled = await require_settle_sources.settleSourcesWithTimeout(this.sources().map((s) => [s.id, async () => {
229
- return (await s.provider.listCalendars()).map((cal) => ({
230
- ...cal,
231
- id: stampId(s.id, cal.id),
232
- providerAddonId: s.id
233
- }));
234
- }]), PER_SOURCE_TIMEOUT_MS);
235
- const out = [];
236
- for (const [sourceId, result] of settled) if (result.ok) for (const entry of result.value) out.push(entry);
237
- else this.ctx.logger.warn("calendar-source provider failed", { meta: {
238
- sourceId,
239
- error: result.error.message
240
- } });
241
- return out;
242
- }
243
- async listEvents(input) {
244
- const sources = this.sources();
245
- const wanted = input.calendarIds !== void 0 ? new Set(input.calendarIds) : null;
246
- const settled = await require_settle_sources.settleSourcesWithTimeout(sources.map((s) => {
247
- const localIds = wanted === null ? void 0 : [...wanted].map((id) => localIdOf(id, s.id)).filter((id) => id !== null);
248
- return [s.id, async () => {
249
- if (wanted !== null && localIds !== void 0 && localIds.length === 0) return [];
250
- return (await s.provider.listEvents({
251
- startMs: input.startMs,
252
- endMs: input.endMs,
253
- ...localIds !== void 0 ? { calendarIds: [...localIds] } : {}
254
- })).map((ev) => ({
255
- ...ev,
256
- calendarId: stampId(s.id, ev.calendarId),
257
- id: stampId(s.id, ev.id)
258
- }));
259
- }];
260
- }), PER_SOURCE_TIMEOUT_MS);
261
- const out = [];
262
- for (const [sourceId, result] of settled) if (result.ok) for (const ev of result.value) out.push(ev);
263
- else this.ctx.logger.warn("calendar-source listEvents failed", { meta: {
264
- sourceId,
265
- error: result.error.message
266
- } });
267
- return out.toSorted((a, b) => a.startMs - b.startMs);
268
- }
269
- async importFromHomeAssistant() {
270
- const ha = this.sources().find((s) => s.id === HA_ADDON_ID || s.id.includes("homeassistant"));
271
- if (ha === void 0) return {
272
- imported: 0,
273
- error: "No Home Assistant calendar-source provider is registered"
274
- };
275
- try {
276
- return {
277
- imported: (await ha.provider.listCalendars()).length,
278
- providerAddonId: ha.id
279
- };
280
- } catch (err) {
281
- return {
282
- imported: 0,
283
- providerAddonId: ha.id,
284
- error: require_dist.errMsg(err)
285
- };
286
- }
287
- }
288
- };
289
- //#endregion
290
190
  //#region src/events/event-bus.ts
291
191
  var EventBus = class {
292
192
  listeners = /* @__PURE__ */ new Map();
@@ -96564,7 +96464,7 @@ exports.CA_VALIDITY_DAYS = require_tls$1.CA_VALIDITY_DAYS;
96564
96464
  exports.CLUSTER_SECRET_MISMATCH_TYPE = CLUSTER_SECRET_MISMATCH_TYPE;
96565
96465
  exports.CLUSTER_SECRET_REJECTED_EXIT_CODE = CLUSTER_SECRET_REJECTED_EXIT_CODE;
96566
96466
  exports.CORE_CAP_SERVICE_NAME = CORE_CAP_SERVICE_NAME;
96567
- exports.CalendarsAddon = CalendarsAddon;
96467
+ exports.CalendarsAddon = require_builtins_calendars_calendars_addon.CalendarsAddon;
96568
96468
  exports.CapRouteError = require_child_cap_dispatch.CapRouteError;
96569
96469
  exports.CapRouteResolver = require_child_cap_dispatch.CapRouteResolver;
96570
96470
  exports.CapUsageRegistry = require_child_cap_dispatch.CapUsageRegistry;
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { $n as asNumber, $t as objectInputDeclaresRequiredDeviceId, C as LOG_LEVEL_RANK, E as METHOD_ACCESS_MAP, Et as extractNestedAddonId, Ft as isVoidInput, Gn as BaseAddon, H as addonSettingsCapability, It as kebabToCamel, Jn as DEVICE_STATUS_METHOD, Kn as DATAPLANE_SECRET_HEADER$1, Mt as isCollectionArrayMethod, Pt as isObjectInput, Qn as asJsonObject$1, Qt as objectInputDeclaresAddonId, Ut as logLevelAtMost, Wn as errMsg$1, Wt as looseSchema, Xn as ReadinessTimeoutError, Yn as ReadinessRegistry, Z as calendarsCapability, dn as scopesAllowAddon, dr as readinessKey, er as asString$1, fn as scopesAllowDeviceCap, fr as resolveCapMount, gr as EventCategory$1, ir as expandCapMethods, j as RUNTIME_DEFAULTS, jt as isArrayOutputSchema, ln as resolveMethodAuth, lr as parseJsonObject, nr as emitDownForOwnedCaps, pr as scopeKey, qn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, rn as procedureAuthKey, t as ALL_CAPABILITY_DEFINITIONS, tr as createEvent, ur as parseJsonUnknown, zt as lifecycleJobSchema } from "./dist-0zO6jHkf.mjs";
2
+ import { $n as asNumber, $t as objectInputDeclaresRequiredDeviceId, C as LOG_LEVEL_RANK, E as METHOD_ACCESS_MAP, Et as extractNestedAddonId, Ft as isVoidInput, H as addonSettingsCapability, It as kebabToCamel, Jn as DEVICE_STATUS_METHOD, Kn as DATAPLANE_SECRET_HEADER$1, Mt as isCollectionArrayMethod, Pt as isObjectInput, Qn as asJsonObject$1, Qt as objectInputDeclaresAddonId, Ut as logLevelAtMost, Wn as errMsg$1, Wt as looseSchema, Xn as ReadinessTimeoutError, Yn as ReadinessRegistry, dn as scopesAllowAddon, dr as readinessKey, er as asString$1, fn as scopesAllowDeviceCap, fr as resolveCapMount, gr as EventCategory$1, ir as expandCapMethods, j as RUNTIME_DEFAULTS, jt as isArrayOutputSchema, ln as resolveMethodAuth, lr as parseJsonObject, nr as emitDownForOwnedCaps, pr as scopeKey, qn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, rn as procedureAuthKey, t as ALL_CAPABILITY_DEFINITIONS, tr as createEvent, ur as parseJsonUnknown, zt as lifecycleJobSchema } from "./dist-0zO6jHkf.mjs";
3
3
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
4
4
  import "./builtins/alerts/index.mjs";
5
- import { t as settleSourcesWithTimeout } from "./settle-sources-CDtNC8ub.mjs";
5
+ import { CalendarsAddon } from "./builtins/calendars/calendars.addon.mjs";
6
+ import "./builtins/calendars/index.mjs";
6
7
  import { ComposerAddon } from "./builtins/composer/composer.addon.mjs";
7
8
  import "./builtins/composer/index.mjs";
8
9
  import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
@@ -179,107 +180,6 @@ function matchPath(pattern, path) {
179
180
  return params;
180
181
  }
181
182
  //#endregion
182
- //#region src/builtins/calendars/calendars.addon.ts
183
- /**
184
- * Hub calendars aggregator — walks `calendar-source` providers and stamps
185
- * cluster-stable ids (`<providerAddonId>:<localId>`).
186
- */
187
- var PER_SOURCE_TIMEOUT_MS = 2500;
188
- var HA_ADDON_ID = "provider-homeassistant";
189
- function stampId(providerAddonId, localId) {
190
- return `${providerAddonId}:${localId}`;
191
- }
192
- function localIdOf(stamped, providerAddonId) {
193
- const prefix = `${providerAddonId}:`;
194
- if (!stamped.startsWith(prefix)) return null;
195
- return stamped.slice(prefix.length);
196
- }
197
- var CalendarsAddon = class extends BaseAddon {
198
- id = "calendars";
199
- constructor() {
200
- super({});
201
- }
202
- async onInitialize() {
203
- const provider = {
204
- listCalendars: async () => this.listCalendars(),
205
- listEvents: async (input) => this.listEvents(input),
206
- importFromHomeAssistant: async () => this.importFromHomeAssistant()
207
- };
208
- this.ctx.logger.info("Initialized — aggregating calendar-source providers");
209
- return [{
210
- capability: calendarsCapability,
211
- provider
212
- }];
213
- }
214
- sources() {
215
- return (this.capabilities?.getCollectionEntries("calendar-source") ?? []).map(([id, provider]) => ({
216
- id,
217
- provider
218
- }));
219
- }
220
- async listCalendars() {
221
- const settled = await settleSourcesWithTimeout(this.sources().map((s) => [s.id, async () => {
222
- return (await s.provider.listCalendars()).map((cal) => ({
223
- ...cal,
224
- id: stampId(s.id, cal.id),
225
- providerAddonId: s.id
226
- }));
227
- }]), PER_SOURCE_TIMEOUT_MS);
228
- const out = [];
229
- for (const [sourceId, result] of settled) if (result.ok) for (const entry of result.value) out.push(entry);
230
- else this.ctx.logger.warn("calendar-source provider failed", { meta: {
231
- sourceId,
232
- error: result.error.message
233
- } });
234
- return out;
235
- }
236
- async listEvents(input) {
237
- const sources = this.sources();
238
- const wanted = input.calendarIds !== void 0 ? new Set(input.calendarIds) : null;
239
- const settled = await settleSourcesWithTimeout(sources.map((s) => {
240
- const localIds = wanted === null ? void 0 : [...wanted].map((id) => localIdOf(id, s.id)).filter((id) => id !== null);
241
- return [s.id, async () => {
242
- if (wanted !== null && localIds !== void 0 && localIds.length === 0) return [];
243
- return (await s.provider.listEvents({
244
- startMs: input.startMs,
245
- endMs: input.endMs,
246
- ...localIds !== void 0 ? { calendarIds: [...localIds] } : {}
247
- })).map((ev) => ({
248
- ...ev,
249
- calendarId: stampId(s.id, ev.calendarId),
250
- id: stampId(s.id, ev.id)
251
- }));
252
- }];
253
- }), PER_SOURCE_TIMEOUT_MS);
254
- const out = [];
255
- for (const [sourceId, result] of settled) if (result.ok) for (const ev of result.value) out.push(ev);
256
- else this.ctx.logger.warn("calendar-source listEvents failed", { meta: {
257
- sourceId,
258
- error: result.error.message
259
- } });
260
- return out.toSorted((a, b) => a.startMs - b.startMs);
261
- }
262
- async importFromHomeAssistant() {
263
- const ha = this.sources().find((s) => s.id === HA_ADDON_ID || s.id.includes("homeassistant"));
264
- if (ha === void 0) return {
265
- imported: 0,
266
- error: "No Home Assistant calendar-source provider is registered"
267
- };
268
- try {
269
- return {
270
- imported: (await ha.provider.listCalendars()).length,
271
- providerAddonId: ha.id
272
- };
273
- } catch (err) {
274
- return {
275
- imported: 0,
276
- providerAddonId: ha.id,
277
- error: errMsg$1(err)
278
- };
279
- }
280
- }
281
- };
282
- //#endregion
283
183
  //#region src/events/event-bus.ts
284
184
  var EventBus = class {
285
185
  listeners = /* @__PURE__ */ new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.344",
3
+ "version": "1.2.345",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",