crewly 1.20.209 → 1.20.210

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.
Files changed (65) hide show
  1. package/config/skills/agent/core/app-data/SKILL.md +88 -0
  2. package/config/skills/agent/core/app-data/execute.sh +141 -0
  3. package/config/skills/agent/core/app-data/execute.test.sh +108 -0
  4. package/config/skills/agent/core/publish-app/SKILL.md +181 -0
  5. package/config/skills/agent/core/publish-app/execute.sh +181 -0
  6. package/config/skills/agent/core/publish-app/execute.test.sh +114 -0
  7. package/dist/backend/backend/src/constants.d.ts +62 -0
  8. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  9. package/dist/backend/backend/src/constants.js +62 -0
  10. package/dist/backend/backend/src/constants.js.map +1 -1
  11. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts +39 -0
  12. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts.map +1 -0
  13. package/dist/backend/backend/src/controllers/apps/apps.controller.js +94 -0
  14. package/dist/backend/backend/src/controllers/apps/apps.controller.js.map +1 -0
  15. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts +46 -0
  16. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts.map +1 -0
  17. package/dist/backend/backend/src/controllers/apps/apps.routes.js +94 -0
  18. package/dist/backend/backend/src/controllers/apps/apps.routes.js.map +1 -0
  19. package/dist/backend/backend/src/index.d.ts +1 -0
  20. package/dist/backend/backend/src/index.d.ts.map +1 -1
  21. package/dist/backend/backend/src/index.js +57 -5
  22. package/dist/backend/backend/src/index.js.map +1 -1
  23. package/dist/backend/backend/src/middleware/body-parser-except.d.ts +25 -0
  24. package/dist/backend/backend/src/middleware/body-parser-except.d.ts.map +1 -0
  25. package/dist/backend/backend/src/middleware/body-parser-except.js +33 -0
  26. package/dist/backend/backend/src/middleware/body-parser-except.js.map +1 -0
  27. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  28. package/dist/backend/backend/src/routes/api.routes.js +4 -0
  29. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  30. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  31. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +4 -0
  32. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  33. package/dist/backend/backend/src/services/apps/app-wake-message.d.ts +95 -0
  34. package/dist/backend/backend/src/services/apps/app-wake-message.d.ts.map +1 -0
  35. package/dist/backend/backend/src/services/apps/app-wake-message.js +161 -0
  36. package/dist/backend/backend/src/services/apps/app-wake-message.js.map +1 -0
  37. package/dist/backend/backend/src/services/apps/app-wake.service.d.ts +118 -0
  38. package/dist/backend/backend/src/services/apps/app-wake.service.d.ts.map +1 -0
  39. package/dist/backend/backend/src/services/apps/app-wake.service.js +325 -0
  40. package/dist/backend/backend/src/services/apps/app-wake.service.js.map +1 -0
  41. package/dist/backend/backend/src/services/apps/apps-cloud.client.d.ts +74 -0
  42. package/dist/backend/backend/src/services/apps/apps-cloud.client.d.ts.map +1 -0
  43. package/dist/backend/backend/src/services/apps/apps-cloud.client.js +120 -0
  44. package/dist/backend/backend/src/services/apps/apps-cloud.client.js.map +1 -0
  45. package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts +107 -0
  46. package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts.map +1 -0
  47. package/dist/backend/backend/src/services/apps/apps-registry.service.js +178 -0
  48. package/dist/backend/backend/src/services/apps/apps-registry.service.js.map +1 -0
  49. package/dist/backend/backend/src/services/apps/apps.service.d.ts +217 -0
  50. package/dist/backend/backend/src/services/apps/apps.service.d.ts.map +1 -0
  51. package/dist/backend/backend/src/services/apps/apps.service.js +383 -0
  52. package/dist/backend/backend/src/services/apps/apps.service.js.map +1 -0
  53. package/dist/backend/backend/src/services/apps/apps.wiring.d.ts +83 -0
  54. package/dist/backend/backend/src/services/apps/apps.wiring.d.ts.map +1 -0
  55. package/dist/backend/backend/src/services/apps/apps.wiring.js +133 -0
  56. package/dist/backend/backend/src/services/apps/apps.wiring.js.map +1 -0
  57. package/dist/backend/build-info.json +2 -2
  58. package/dist/cli/backend/src/constants.d.ts +62 -0
  59. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  60. package/dist/cli/backend/src/constants.js +62 -0
  61. package/dist/cli/backend/src/constants.js.map +1 -1
  62. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  63. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +4 -0
  64. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-registry.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/apps/apps-registry.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,uCAAuC;AACvC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,uFAAuF;IACvF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,8DAA8D;IAC9D,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uHAAuH;IACvH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,gHAAgH;IAChH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAMD,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,KAAK,CAAuC;IAEpD;;OAEG;gBACS,UAAU,EAAE,MAAM;YAIhB,IAAI;IAQlB,OAAO,CAAC,MAAM;IAYd;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAKzC;;;;;OAKG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAM1D;;;;;;;OAOG;IACG,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgB1D;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuBjG;;;;;;;OAOG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAepF;;;;;;OAMG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9E;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAShD"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * AppsRegistryService — the apps this instance published, kept in
3
+ * `<CREWLY_HOME>/apps/registry.json`.
4
+ *
5
+ * It answers two questions: which app an agent's publish goes to (so the
6
+ * same agent republishing the same directory lands on the same app), and
7
+ * which agent to wake when an app changes. It also keeps each app's change
8
+ * cursor for the poller (specs/2026-10-04-crewly-apps-p2.md §2, §5).
9
+ *
10
+ * @module services/apps/apps-registry.service
11
+ */
12
+ import { promises as fs } from 'fs';
13
+ import path from 'path';
14
+ import { CREWLY_APPS_CONSTANTS } from '../../constants.js';
15
+ import { atomicWriteJson, safeReadJson } from '../../utils/file-io.utils.js';
16
+ /**
17
+ * File-backed registry. All writes are serialised in-process.
18
+ */
19
+ export class AppsRegistryService {
20
+ file;
21
+ data = null;
22
+ chain = Promise.resolve();
23
+ /**
24
+ * @param crewlyHome - CREWLY_HOME directory
25
+ */
26
+ constructor(crewlyHome) {
27
+ this.file = path.join(crewlyHome, CREWLY_APPS_CONSTANTS.REGISTRY_DIR, CREWLY_APPS_CONSTANTS.REGISTRY_FILE);
28
+ }
29
+ async load() {
30
+ if (!this.data) {
31
+ const raw = await safeReadJson(this.file, { apps: {} });
32
+ this.data = raw && typeof raw === 'object' && raw.apps && typeof raw.apps === 'object' ? raw : { apps: {} };
33
+ }
34
+ return this.data;
35
+ }
36
+ mutate(fn) {
37
+ const run = this.chain.then(async () => {
38
+ const d = await this.load();
39
+ const out = fn(d);
40
+ await fs.mkdir(path.dirname(this.file), { recursive: true });
41
+ await atomicWriteJson(this.file, d);
42
+ return out;
43
+ });
44
+ this.chain = run.catch(() => undefined);
45
+ return run;
46
+ }
47
+ /**
48
+ * Every app, deleted ones included.
49
+ *
50
+ * @returns Copies of the entries
51
+ */
52
+ async list() {
53
+ const d = await this.load();
54
+ return Object.values(d.apps).map((e) => ({ ...e }));
55
+ }
56
+ /**
57
+ * One app by id.
58
+ *
59
+ * @param appId - App id
60
+ * @returns A copy, or null
61
+ */
62
+ async get(appId) {
63
+ const d = await this.load();
64
+ const e = d.apps[appId];
65
+ return e ? { ...e } : null;
66
+ }
67
+ /**
68
+ * The app a publish should go to: explicit id; else the same agent and
69
+ * source; else the same agent and name (case-insensitive). Deleted apps
70
+ * never match implicitly.
71
+ *
72
+ * @param q - Lookup keys
73
+ * @returns The entry, or null (create a new app)
74
+ */
75
+ async find(q) {
76
+ const d = await this.load();
77
+ if (q.appId)
78
+ return d.apps[q.appId] ? { ...d.apps[q.appId] } : null;
79
+ const mine = Object.values(d.apps).filter((e) => !e.deleted && (e.agentSession ?? null) === (q.agentSession ?? null));
80
+ if (q.source) {
81
+ const bySource = mine.find((e) => e.source === q.source);
82
+ if (bySource)
83
+ return { ...bySource };
84
+ }
85
+ if (q.name) {
86
+ const n = q.name.trim().toLowerCase();
87
+ const byName = mine.find((e) => e.name.trim().toLowerCase() === n);
88
+ if (byName)
89
+ return { ...byName };
90
+ }
91
+ return null;
92
+ }
93
+ /**
94
+ * Insert or update an entry (fields given replace the stored ones).
95
+ *
96
+ * @param appId - App id
97
+ * @param patch - Fields to set
98
+ * @returns The stored entry
99
+ */
100
+ upsert(appId, patch) {
101
+ return this.mutate((d) => {
102
+ const now = new Date().toISOString();
103
+ const prev = d.apps[appId];
104
+ const next = {
105
+ appId,
106
+ name: patch.name ?? prev?.name ?? appId,
107
+ url: patch.url ?? prev?.url ?? `${CREWLY_APPS_CONSTANTS.APPS_ORIGIN}/${appId}`,
108
+ agentSession: patch.agentSession !== undefined ? patch.agentSession : prev?.agentSession ?? null,
109
+ source: patch.source !== undefined ? patch.source : prev?.source ?? null,
110
+ currentVersion: patch.currentVersion !== undefined ? patch.currentVersion : prev?.currentVersion ?? null,
111
+ cursor: patch.cursor !== undefined ? patch.cursor : prev?.cursor ?? null,
112
+ createdAt: prev?.createdAt ?? now,
113
+ updatedAt: now,
114
+ ...(patch.deleted !== undefined ? { deleted: patch.deleted } : prev?.deleted ? { deleted: prev.deleted } : {}),
115
+ ...(prev?.wakes ? { wakes: prev.wakes } : {}),
116
+ ...(prev?.delivered && patch.cursor === undefined ? { delivered: prev.delivered } : {}),
117
+ };
118
+ d.apps[appId] = next;
119
+ return { ...next };
120
+ });
121
+ }
122
+ /**
123
+ * Store the poller's progress: the cursor and the seqs above it that were
124
+ * already delivered (no-op for an unknown app or no change).
125
+ *
126
+ * @param appId - App id
127
+ * @param cursor - Safe cursor (before every undelivered change)
128
+ * @param delivered - Delivered seqs above the cursor
129
+ */
130
+ async setProgress(appId, cursor, delivered) {
131
+ const current = (await this.load()).apps[appId];
132
+ if (!current)
133
+ return;
134
+ const sorted = [...delivered].filter((n) => n > cursor).sort((a, b) => a - b);
135
+ const same = current.cursor === cursor && JSON.stringify(current.delivered ?? []) === JSON.stringify(sorted);
136
+ if (same)
137
+ return;
138
+ await this.mutate((d) => {
139
+ const e = d.apps[appId];
140
+ if (!e)
141
+ return;
142
+ e.cursor = cursor;
143
+ if (sorted.length > 0)
144
+ e.delivered = sorted;
145
+ else
146
+ delete e.delivered;
147
+ });
148
+ }
149
+ /**
150
+ * Record a successful wake for the cooldown.
151
+ *
152
+ * @param appId - App id
153
+ * @param recipient - Session or orchestrator key
154
+ * @param at - Epoch ms
155
+ */
156
+ async setLastWake(appId, recipient, at) {
157
+ await this.mutate((d) => {
158
+ const e = d.apps[appId];
159
+ if (e)
160
+ e.wakes = { ...(e.wakes ?? {}), [recipient]: at };
161
+ });
162
+ }
163
+ /**
164
+ * Mark an app gone from Cloud.
165
+ *
166
+ * @param appId - App id
167
+ */
168
+ async markDeleted(appId) {
169
+ await this.mutate((d) => {
170
+ const e = d.apps[appId];
171
+ if (e) {
172
+ e.deleted = true;
173
+ e.updatedAt = new Date().toISOString();
174
+ }
175
+ });
176
+ }
177
+ }
178
+ //# sourceMappingURL=apps-registry.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-registry.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/apps/apps-registry.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAoC7E;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACb,IAAI,CAAS;IACtB,IAAI,GAAwB,IAAI,CAAC;IACjC,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEpD;;OAEG;IACH,YAAY,UAAkB;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,YAAY,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC7G,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,MAAM,YAAY,CAAe,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACtE,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9G,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAEO,MAAM,CAAI,EAA0B;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACrC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7D,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACpC,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACxC,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,KAAa;QACrB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,CAAY;QACrB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC;QACtH,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,QAAQ;gBAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;YACnE,IAAI,MAAM;gBAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAa,EAAE,KAA+C;QACnE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACvB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,IAAI,GAAqB;gBAC7B,KAAK;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK;gBACvC,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,GAAG,qBAAqB,CAAC,WAAW,IAAI,KAAK,EAAE;gBAC9E,YAAY,EAAE,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,IAAI,IAAI;gBAChG,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI;gBACxE,cAAc,EAAE,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,IAAI,IAAI;gBACxG,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI;gBACxE,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,GAAG;gBACjC,SAAS,EAAE,GAAG;gBACd,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9G,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxF,CAAC;YACF,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YACrB,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,MAAc,EAAE,SAAmB;QAClE,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7G,IAAI,IAAI;YAAE,OAAO;QACjB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,CAAC;gBAAE,OAAO;YACf,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;YAClB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC;;gBACvC,OAAO,CAAC,CAAC,SAAS,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,SAAiB,EAAE,EAAU;QAC5D,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC;gBAAE,CAAC,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,EAAE,CAAC;gBACN,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * AppsService — publish, roll back and read/write the data of Crewly Apps
3
+ * on behalf of an agent (or the owner), through {@link AppsCloudClient}.
4
+ *
5
+ * Backs `/api/apps` and the publish-app / app-data skills
6
+ * (specs/2026-10-04-crewly-apps-p2.md).
7
+ *
8
+ * @module services/apps/apps.service
9
+ */
10
+ import { AppsCloudClient } from './apps-cloud.client.js';
11
+ import type { AppRegistryEntry, AppsRegistryService } from './apps-registry.service.js';
12
+ /** Cloud's view of an app (apps/SPEC.md §3.1). */
13
+ export interface CloudAppView {
14
+ appId: string;
15
+ name: string;
16
+ slug: string | null;
17
+ url: string;
18
+ currentVersion: number | null;
19
+ latestVersion: number;
20
+ }
21
+ /** Cloud's view of a version. */
22
+ export interface CloudVersionView {
23
+ version: number;
24
+ entry: string;
25
+ files: number;
26
+ totalBytes: number;
27
+ note: string | null;
28
+ createdAt: string;
29
+ current: boolean;
30
+ }
31
+ /** One bundle file as the skill sends it. */
32
+ export interface PublishFile {
33
+ path: string;
34
+ contentBase64: string;
35
+ contentType?: string;
36
+ }
37
+ /** Input of {@link AppsService.publish}. */
38
+ export interface PublishInput {
39
+ files: unknown;
40
+ name?: unknown;
41
+ appId?: unknown;
42
+ source?: unknown;
43
+ entry?: unknown;
44
+ note?: unknown;
45
+ notify?: unknown;
46
+ }
47
+ /** Result of a publish. */
48
+ export interface PublishResult {
49
+ appId: string;
50
+ name: string;
51
+ url: string;
52
+ version: number;
53
+ created: boolean;
54
+ notified: boolean;
55
+ notifyError?: string;
56
+ }
57
+ /** Who is calling: an agent session, or the owner (no session). */
58
+ export interface AppsCaller {
59
+ agentSession?: string;
60
+ }
61
+ /** Posts the "Open app" card where the agent talks with the owner. */
62
+ export type AppCardNotifier = (agentSession: string, text: string) => Promise<{
63
+ ok: boolean;
64
+ error?: string;
65
+ }>;
66
+ /** Constructor dependencies. */
67
+ export interface AppsServiceDeps {
68
+ client: AppsCloudClient;
69
+ registry: AppsRegistryService;
70
+ notifyCard?: AppCardNotifier;
71
+ /** Whether two agent sessions are in the same team (data access for the publisher's team) */
72
+ sameTeam?: (a: string, b: string) => Promise<boolean>;
73
+ }
74
+ /**
75
+ * Check an app id's shape.
76
+ *
77
+ * @param appId - Candidate
78
+ * @returns The id
79
+ * @throws AppsCloudError validation
80
+ */
81
+ export declare function requireAppId(appId: unknown): string;
82
+ /**
83
+ * The "📱 <name> · Open app" card text. Markdown link: the reply path turns
84
+ * it into a Slack link.
85
+ *
86
+ * @param name - App name
87
+ * @param appId - App id
88
+ * @returns Card text
89
+ */
90
+ export declare function appCardText(name: string, appId: string): string;
91
+ /**
92
+ * Publishing and data access for Crewly Apps.
93
+ */
94
+ export declare class AppsService {
95
+ private readonly deps;
96
+ constructor(deps: AppsServiceDeps);
97
+ /**
98
+ * Publish a bundle: find the caller's app (or create one), upload a new
99
+ * version, record it locally, and optionally post the Slack card.
100
+ *
101
+ * @param input - Files and options from the skill
102
+ * @param caller - Agent session or owner
103
+ * @returns appId, url, version, whether it was created / notified
104
+ * @throws AppsCloudError on validation or a Cloud failure
105
+ */
106
+ publish(input: PublishInput, caller: AppsCaller): Promise<PublishResult>;
107
+ /**
108
+ * Make an earlier retained version current.
109
+ *
110
+ * @param appId - App id
111
+ * @param version - Version number
112
+ * @param caller - Agent or owner
113
+ * @returns The app after rollback
114
+ */
115
+ rollback(appId: unknown, version: unknown, caller: AppsCaller): Promise<CloudAppView>;
116
+ /**
117
+ * Versions of an app, newest first.
118
+ *
119
+ * @param appId - App id
120
+ * @param caller - Agent or owner
121
+ * @returns Versions
122
+ */
123
+ versions(appId: unknown, caller: AppsCaller): Promise<CloudVersionView[]>;
124
+ /**
125
+ * Agents may manage (publish, roll back, list versions of) only apps they
126
+ * published. The owner may manage any.
127
+ *
128
+ * @param appId - App id
129
+ * @param caller - Agent or owner
130
+ * @throws AppsCloudError 403 not_your_app
131
+ */
132
+ assertPublisher(appId: string, caller: AppsCaller): Promise<void>;
133
+ /**
134
+ * Agents may read and write the data of apps they published, or that a
135
+ * teammate published. The owner may use any.
136
+ *
137
+ * @param appId - App id
138
+ * @param caller - Agent or owner
139
+ * @throws AppsCloudError 403 not_your_app
140
+ */
141
+ assertDataAccess(appId: string, caller: AppsCaller): Promise<void>;
142
+ /**
143
+ * Apps this instance published (local registry, not Cloud).
144
+ *
145
+ * @returns Entries without the poller cursor
146
+ */
147
+ list(caller?: AppsCaller): Promise<Array<Omit<AppRegistryEntry, 'cursor' | 'delivered' | 'wakes'>>>;
148
+ /**
149
+ * One page of a collection.
150
+ *
151
+ * @param appId - App id
152
+ * @param collection - Collection
153
+ * @param opts - limit / after
154
+ * @param caller - Agent or owner
155
+ * @returns `{ docs, next }`
156
+ */
157
+ listDocs(appId: unknown, collection: unknown, opts: {
158
+ limit?: unknown;
159
+ after?: unknown;
160
+ }, caller: AppsCaller): Promise<unknown>;
161
+ /**
162
+ * One document (`{ id, data, rev, … }`); a missing one throws 404 not_found.
163
+ *
164
+ * @param appId - App id
165
+ * @param collection - Collection
166
+ * @param docId - Document id
167
+ * @param caller - Agent or owner
168
+ * @returns The document
169
+ */
170
+ getDoc(appId: unknown, collection: unknown, docId: unknown, caller: AppsCaller): Promise<unknown>;
171
+ /**
172
+ * Replace (or create) a document.
173
+ *
174
+ * @param appId - App id
175
+ * @param collection - Collection
176
+ * @param docId - Document id
177
+ * @param data - New content
178
+ * @param caller - Agent or owner
179
+ * @returns The stored document
180
+ */
181
+ setDoc(appId: unknown, collection: unknown, docId: unknown, data: unknown, caller: AppsCaller): Promise<unknown>;
182
+ /**
183
+ * Shallow-merge into a document; `ifRev` makes it conditional (409 conflict).
184
+ *
185
+ * @param appId - App id
186
+ * @param collection - Collection
187
+ * @param docId - Document id
188
+ * @param data - Fields to merge
189
+ * @param ifRev - Expected current rev (optional)
190
+ * @param caller - Agent or owner
191
+ * @returns The stored document
192
+ */
193
+ updateDoc(appId: unknown, collection: unknown, docId: unknown, data: unknown, ifRev: unknown, caller: AppsCaller): Promise<unknown>;
194
+ /**
195
+ * Add a document with a generated id.
196
+ *
197
+ * @param appId - App id
198
+ * @param collection - Collection
199
+ * @param data - Content
200
+ * @param caller - Agent or owner
201
+ * @returns The stored document
202
+ */
203
+ addDoc(appId: unknown, collection: unknown, data: unknown, caller: AppsCaller): Promise<unknown>;
204
+ /**
205
+ * Delete a document.
206
+ *
207
+ * @param appId - App id
208
+ * @param collection - Collection
209
+ * @param docId - Document id
210
+ * @param caller - Agent or owner
211
+ * @returns `{ deleted: true }`
212
+ */
213
+ deleteDoc(appId: unknown, collection: unknown, docId: unknown, caller: AppsCaller): Promise<unknown>;
214
+ private docPath;
215
+ private validateFiles;
216
+ }
217
+ //# sourceMappingURL=apps.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/apps/apps.service.ts"],"names":[],"mappings":"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"}