@raidiant/notifai 10.1.0 → 10.1.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.
Files changed (204) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +3 -0
  3. package/dist/cli-bin.d.ts +21 -1
  4. package/dist/cli-bin.js +141 -10
  5. package/dist/cli-bin.js.map +1 -1
  6. package/dist/cli-update-contract.d.ts +7 -0
  7. package/dist/cli-update-contract.js +10 -0
  8. package/dist/cli-update-contract.js.map +1 -0
  9. package/dist/client.d.ts +6 -1
  10. package/dist/client.js +1 -0
  11. package/dist/client.js.map +1 -1
  12. package/dist/codex-wake.d.ts +2 -0
  13. package/dist/codex-wake.js +2 -1
  14. package/dist/codex-wake.js.map +1 -1
  15. package/dist/commands-auth.d.ts +15 -1
  16. package/dist/commands-auth.js +29 -11
  17. package/dist/commands-auth.js.map +1 -1
  18. package/dist/commands-core.d.ts +9 -2
  19. package/dist/commands-core.js +11 -4
  20. package/dist/commands-core.js.map +1 -1
  21. package/dist/commands-devices.d.ts +10 -1
  22. package/dist/commands-devices.js +17 -13
  23. package/dist/commands-devices.js.map +1 -1
  24. package/dist/commands-doctor.js +93 -49
  25. package/dist/commands-doctor.js.map +1 -1
  26. package/dist/commands-hooks.js +47 -10
  27. package/dist/commands-hooks.js.map +1 -1
  28. package/dist/commands-init.d.ts +16 -0
  29. package/dist/commands-init.js +254 -93
  30. package/dist/commands-init.js.map +1 -1
  31. package/dist/commands-send-support.js +3 -0
  32. package/dist/commands-send-support.js.map +1 -1
  33. package/dist/commands-send.d.ts +1 -1
  34. package/dist/commands-send.js +121 -35
  35. package/dist/commands-send.js.map +1 -1
  36. package/dist/commands-skill.js +72 -54
  37. package/dist/commands-skill.js.map +1 -1
  38. package/dist/commands-update.d.ts +10 -0
  39. package/dist/commands-update.js +141 -0
  40. package/dist/commands-update.js.map +1 -0
  41. package/dist/commands.d.ts +2 -1
  42. package/dist/commands.js +2 -1
  43. package/dist/commands.js.map +1 -1
  44. package/dist/hook-adapter.d.ts +2 -0
  45. package/dist/hook-adapter.js +12 -1
  46. package/dist/hook-adapter.js.map +1 -1
  47. package/dist/hooks.d.ts +43 -2
  48. package/dist/hooks.js +163 -21
  49. package/dist/hooks.js.map +1 -1
  50. package/dist/invocation-context.d.ts +1 -0
  51. package/dist/invocation-context.js +9 -1
  52. package/dist/invocation-context.js.map +1 -1
  53. package/dist/main-run.d.ts +1 -0
  54. package/dist/main-run.js +42 -0
  55. package/dist/main-run.js.map +1 -0
  56. package/dist/main.js +10 -31
  57. package/dist/main.js.map +1 -1
  58. package/dist/native-skills.d.ts +13 -3
  59. package/dist/native-skills.js +51 -12
  60. package/dist/native-skills.js.map +1 -1
  61. package/dist/node-floor.d.ts +19 -0
  62. package/dist/node-floor.js +39 -0
  63. package/dist/node-floor.js.map +1 -0
  64. package/dist/orca-session-title.d.ts +5 -4
  65. package/dist/orca-session-title.js +32 -19
  66. package/dist/orca-session-title.js.map +1 -1
  67. package/dist/platform.d.ts +11 -17
  68. package/dist/platform.js +20 -23
  69. package/dist/platform.js.map +1 -1
  70. package/dist/program.d.ts +2 -1
  71. package/dist/program.js +22 -5
  72. package/dist/program.js.map +1 -1
  73. package/dist/question-settlement-process.d.ts +15 -0
  74. package/dist/question-settlement-process.js +35 -0
  75. package/dist/question-settlement-process.js.map +1 -0
  76. package/dist/readiness.d.ts +25 -1
  77. package/dist/readiness.js +32 -2
  78. package/dist/readiness.js.map +1 -1
  79. package/dist/release.d.ts +5 -5
  80. package/dist/release.js +5 -5
  81. package/dist/setup-destinations.d.ts +23 -0
  82. package/dist/setup-destinations.js +44 -0
  83. package/dist/setup-destinations.js.map +1 -0
  84. package/dist/skill-integrity.d.ts +49 -0
  85. package/dist/skill-integrity.js +154 -0
  86. package/dist/skill-integrity.js.map +1 -0
  87. package/dist/skill-source/manifest.json +16 -0
  88. package/dist/skill-source/notifai/SKILL.md +390 -0
  89. package/dist/skill-source/notifai/references/harness-setup.md +220 -0
  90. package/package.json +11 -14
  91. package/src/atomic-file.ts +0 -198
  92. package/src/claude-wake.test.ts +0 -321
  93. package/src/claude-wake.ts +0 -499
  94. package/src/cli-bin.test.ts +0 -38
  95. package/src/cli-bin.ts +0 -67
  96. package/src/cli-release.test.ts +0 -46
  97. package/src/cli-release.ts +0 -78
  98. package/src/client.test.ts +0 -390
  99. package/src/client.ts +0 -345
  100. package/src/codex-wake.test.ts +0 -254
  101. package/src/codex-wake.ts +0 -297
  102. package/src/command-session.ts +0 -38
  103. package/src/commands-agent-sessions.ts +0 -72
  104. package/src/commands-auth.ts +0 -205
  105. package/src/commands-config.ts +0 -336
  106. package/src/commands-core.ts +0 -298
  107. package/src/commands-devices.test.ts +0 -15
  108. package/src/commands-devices.ts +0 -173
  109. package/src/commands-doctor.ts +0 -1440
  110. package/src/commands-guidance.ts +0 -181
  111. package/src/commands-harness-context.ts +0 -207
  112. package/src/commands-hook-shape.ts +0 -69
  113. package/src/commands-hooks.ts +0 -2268
  114. package/src/commands-init.ts +0 -878
  115. package/src/commands-io.ts +0 -108
  116. package/src/commands-logs.ts +0 -243
  117. package/src/commands-project.ts +0 -47
  118. package/src/commands-send-support.test.ts +0 -156
  119. package/src/commands-send-support.ts +0 -311
  120. package/src/commands-send.ts +0 -769
  121. package/src/commands-setup-proof.test.ts +0 -72
  122. package/src/commands-setup-proof.ts +0 -124
  123. package/src/commands-skill.test.ts +0 -44
  124. package/src/commands-skill.ts +0 -204
  125. package/src/commands-sounds.test.ts +0 -106
  126. package/src/commands-sounds.ts +0 -49
  127. package/src/commands.test.ts +0 -7828
  128. package/src/commands.ts +0 -75
  129. package/src/config-schema.test.ts +0 -153
  130. package/src/config-schema.ts +0 -349
  131. package/src/config.test.ts +0 -581
  132. package/src/config.ts +0 -475
  133. package/src/credentials.test.ts +0 -403
  134. package/src/credentials.ts +0 -403
  135. package/src/file-lock-process-worker.test.ts +0 -64
  136. package/src/file-lock.test.ts +0 -320
  137. package/src/file-lock.ts +0 -393
  138. package/src/fixtures/hermes-0.20.6-classic-cli-local.json +0 -50
  139. package/src/fixtures/openclaw-2026.7.1-2-agent-local.json +0 -57
  140. package/src/generated-session-label.ts +0 -155
  141. package/src/guidance-content.ts +0 -278
  142. package/src/guidance-render.ts +0 -56
  143. package/src/guidance.test.ts +0 -327
  144. package/src/guidance.ts +0 -233
  145. package/src/harness-integration.test.ts +0 -294
  146. package/src/harnesses.test.ts +0 -149
  147. package/src/harnesses.ts +0 -164
  148. package/src/hook-adapter.test.ts +0 -496
  149. package/src/hook-adapter.ts +0 -410
  150. package/src/hook-input.test.ts +0 -39
  151. package/src/hook-input.ts +0 -72
  152. package/src/hooks.test.ts +0 -5549
  153. package/src/hooks.ts +0 -3759
  154. package/src/install-hooks.test.ts +0 -1614
  155. package/src/install-hooks.ts +0 -1501
  156. package/src/interactive.test.ts +0 -387
  157. package/src/interactive.ts +0 -858
  158. package/src/invocation-context.test.ts +0 -352
  159. package/src/invocation-context.ts +0 -197
  160. package/src/logging-process-worker.test.ts +0 -45
  161. package/src/logging.test.ts +0 -544
  162. package/src/logging.ts +0 -698
  163. package/src/main.ts +0 -36
  164. package/src/native-skills.test.ts +0 -115
  165. package/src/native-skills.ts +0 -162
  166. package/src/onboarding-docs.test.ts +0 -25
  167. package/src/openclaw-plugin.ts +0 -409
  168. package/src/opencode-plugin.ts +0 -298
  169. package/src/orca-session-title.test.ts +0 -54
  170. package/src/orca-session-title.ts +0 -103
  171. package/src/pack-feedback-slice.test.ts +0 -212
  172. package/src/pack-feedback-slice.ts +0 -187
  173. package/src/platform.test.ts +0 -152
  174. package/src/platform.ts +0 -173
  175. package/src/program.test.ts +0 -282
  176. package/src/program.ts +0 -818
  177. package/src/project-enablement.test.ts +0 -55
  178. package/src/project-enablement.ts +0 -99
  179. package/src/question-caps.test.ts +0 -49
  180. package/src/question-timing.ts +0 -56
  181. package/src/readiness.test.ts +0 -25
  182. package/src/readiness.ts +0 -179
  183. package/src/release.ts +0 -51
  184. package/src/send-attempts.test.ts +0 -143
  185. package/src/send-attempts.ts +0 -188
  186. package/src/send.test.ts +0 -28
  187. package/src/send.ts +0 -436
  188. package/src/session-activation.ts +0 -61
  189. package/src/session-end-log-lock-worker.test.ts +0 -35
  190. package/src/session-labels.test.ts +0 -490
  191. package/src/session-labels.ts +0 -474
  192. package/src/skill.test.ts +0 -415
  193. package/src/sound-ref.test.ts +0 -31
  194. package/src/sound-ref.ts +0 -34
  195. package/src/trust-policy.test.ts +0 -701
  196. package/src/ui/banner.ts +0 -95
  197. package/src/ui/config-view.test.ts +0 -90
  198. package/src/ui/config-view.ts +0 -138
  199. package/src/ui/help.test.ts +0 -16
  200. package/src/ui/help.ts +0 -128
  201. package/src/ui/theme.test.ts +0 -92
  202. package/src/ui/theme.ts +0 -265
  203. package/src/url-policy.ts +0 -399
  204. package/tsconfig.json +0 -10
package/src/main.ts DELETED
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- import { realIo, type CommandDeps } from './commands.js'
3
- import { defaultCredentialStore } from './credentials.js'
4
- import { nativeSkills } from './native-skills.js'
5
- import { argvFlagNames, bootstrapLogger } from './logging.js'
6
- import { buildProgram } from './program.js'
7
-
8
- /**
9
- * The local record for this invocation.
10
- *
11
- * Built before the command tree so that the very first thing recorded is the
12
- * command starting — including for a command that goes on to fail before it has
13
- * resolved anything. It configures itself from disk and disables itself if it
14
- * cannot write, so nothing below has to handle it failing.
15
- */
16
- const logger = bootstrapLogger()
17
-
18
- const deps: CommandDeps = {
19
- io: realIo(),
20
- store: defaultCredentialStore(),
21
- env: process.env,
22
- cwd: process.cwd(),
23
- nativeSkills,
24
- logger,
25
- }
26
-
27
- const startedAt = Date.now()
28
- process.on('exit', (code) => {
29
- logger.info('cli.end', {
30
- exit: code,
31
- duration_ms: Date.now() - startedAt,
32
- flags: argvFlagNames(process.argv.slice(2)),
33
- })
34
- })
35
-
36
- await buildProgram(deps).parseAsync(process.argv)
@@ -1,115 +0,0 @@
1
- import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs'
2
- import os from 'node:os'
3
- import path from 'node:path'
4
- import { describe, expect, it } from 'vitest'
5
- import { SKILLS_INSTALLER_SPEC, nativeSkills, skillsAddArgv, skillsRemoveArgv } from './native-skills.js'
6
-
7
- function writeLock(file: string, ref: string): void {
8
- mkdirSync(path.dirname(file), { recursive: true })
9
- writeFileSync(
10
- file,
11
- `${JSON.stringify({
12
- version: 1,
13
- skills: {
14
- notifai: {
15
- source: 'Raidiant-io/notifai',
16
- sourceType: 'github',
17
- sourceUrl: 'https://github.com/Raidiant-io/notifai.git',
18
- ref,
19
- },
20
- },
21
- })}\n`,
22
- )
23
- }
24
-
25
- describe('skillsAddArgv', () => {
26
- it('pins the installer package to an exact reviewed version', () => {
27
- const argv = skillsAddArgv({
28
- source: 'Raidiant-io/notifai#v8.0.0',
29
- skill: 'notifai',
30
- cwd: '/tmp',
31
- env: {},
32
- })
33
- expect(SKILLS_INSTALLER_SPEC).toMatch(/^skills@\d+\.\d+\.\d+$/)
34
- expect(argv).toEqual([
35
- '-y',
36
- SKILLS_INSTALLER_SPEC,
37
- 'add',
38
- 'Raidiant-io/notifai#v8.0.0',
39
- '--skill',
40
- 'notifai',
41
- ])
42
- expect(argv).not.toContain('skills')
43
- })
44
-
45
- it('uninstalls one skill in the named scope without a prompt', () => {
46
- expect(
47
- skillsRemoveArgv({
48
- skill: 'notifai',
49
- scope: 'project',
50
- cwd: '/tmp',
51
- env: {},
52
- }),
53
- ).toEqual(['-y', SKILLS_INSTALLER_SPEC, 'remove', 'notifai', '--yes'])
54
- expect(
55
- skillsRemoveArgv({
56
- skill: 'notifai',
57
- scope: 'global',
58
- cwd: '/tmp',
59
- env: {},
60
- }),
61
- ).toEqual(['-y', SKILLS_INSTALLER_SPEC, 'remove', 'notifai', '--global', '--yes'])
62
- })
63
- })
64
-
65
- describe('nativeSkills.list', () => {
66
- it('reads the project lock file instead of spawning npx', async () => {
67
- const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-skills-project-'))
68
- writeLock(path.join(cwd, 'skills-lock.json'), 'v0.5.1')
69
-
70
- const result = await nativeSkills.list('project', cwd, { PATH: '/nonexistent' })
71
- expect(result.error).toBeUndefined()
72
- expect(result.skills).toEqual([
73
- expect.objectContaining({
74
- name: 'notifai',
75
- scope: 'project',
76
- source: 'Raidiant-io/notifai',
77
- sourceType: 'github',
78
- ref: 'v0.5.1',
79
- }),
80
- ])
81
- })
82
-
83
- it('reads the XDG global lock file instead of spawning npx', async () => {
84
- const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-skills-xdg-'))
85
- const state = path.join(cwd, 'state')
86
- writeLock(path.join(state, 'skills', '.skill-lock.json'), 'v0.4.0')
87
-
88
- const result = await nativeSkills.list('global', cwd, {
89
- PATH: '/nonexistent',
90
- XDG_STATE_HOME: state,
91
- })
92
- expect(result.error).toBeUndefined()
93
- expect(result.skills).toEqual([
94
- expect.objectContaining({ name: 'notifai', scope: 'global', ref: 'v0.4.0' }),
95
- ])
96
- })
97
-
98
- it('falls back to the home-directory global lock', async () => {
99
- const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-skills-home-'))
100
- const home = path.join(cwd, 'home')
101
- writeLock(path.join(home, '.agents', '.skill-lock.json'), 'v0.3.0')
102
-
103
- const result = await nativeSkills.list('global', cwd, { PATH: '/nonexistent', HOME: home })
104
- expect(result.error).toBeUndefined()
105
- expect(result.skills).toEqual([
106
- expect.objectContaining({ name: 'notifai', scope: 'global', ref: 'v0.3.0' }),
107
- ])
108
- })
109
-
110
- it('treats a missing lock as an empty inventory, not an installer error', async () => {
111
- const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-skills-missing-'))
112
- const result = await nativeSkills.list('project', cwd, { PATH: '/nonexistent' })
113
- expect(result).toEqual({ skills: [] })
114
- })
115
- })
@@ -1,162 +0,0 @@
1
- import { spawn } from 'node:child_process'
2
- import { existsSync, readFileSync } from 'node:fs'
3
- import path from 'node:path'
4
- import { accountHome, npxLaunch } from './platform.js'
5
-
6
- /**
7
- * Exact reviewed version of the external `skills` installer.
8
- *
9
- * The GitHub skill source stays the immutable CLI version tag. The installer
10
- * program that fetches it must not float on `latest`.
11
- */
12
- export const SKILLS_INSTALLER_SPEC = 'skills@1.5.23'
13
-
14
- /** The two scopes offered by the skills installer. */
15
- export type SkillScope = 'project' | 'global'
16
-
17
- /** The installer-managed evidence needed by Notifai readiness. */
18
- export interface NativeSkill {
19
- name: string
20
- scope: SkillScope
21
- path: string
22
- source: string | null
23
- sourceType: string | null
24
- sourceUrl: string | null
25
- ref: string | null
26
- }
27
-
28
- export interface SkillsListResult {
29
- skills: NativeSkill[]
30
- error?: string
31
- }
32
-
33
- export interface SkillsAddOptions {
34
- source: string
35
- skill: string
36
- scope?: SkillScope
37
- cwd: string
38
- env: NodeJS.ProcessEnv
39
- }
40
-
41
- export interface SkillsRemoveOptions {
42
- skill: string
43
- scope: SkillScope
44
- cwd: string
45
- env: NodeJS.ProcessEnv
46
- }
47
-
48
- export interface NativeSkills {
49
- /** Launch the native interactive `npx skills add` flow. */
50
- add(options: SkillsAddOptions): Promise<number>
51
- /** Uninstall one installer-managed skill in one scope. */
52
- remove(options: SkillsRemoveOptions): Promise<number>
53
- /** Read installer-managed inventory from lock files. Does not spawn npx. */
54
- list(scope: SkillScope, cwd: string, env: NodeJS.ProcessEnv): Promise<SkillsListResult>
55
- }
56
-
57
- interface LockEntry {
58
- source?: unknown
59
- sourceType?: unknown
60
- sourceUrl?: unknown
61
- ref?: unknown
62
- skillPath?: unknown
63
- }
64
-
65
- interface LockFile {
66
- skills?: Record<string, LockEntry>
67
- }
68
-
69
- function skillLockPath(scope: SkillScope, cwd: string, env: NodeJS.ProcessEnv): string {
70
- if (scope === 'project') return path.join(cwd, 'skills-lock.json')
71
- const stateHome = env['XDG_STATE_HOME']
72
- return stateHome !== undefined && stateHome !== ''
73
- ? path.join(stateHome, 'skills', '.skill-lock.json')
74
- : path.join(accountHome(env), '.agents', '.skill-lock.json')
75
- }
76
-
77
- function readLock(scope: SkillScope, cwd: string, env: NodeJS.ProcessEnv): LockFile {
78
- const file = skillLockPath(scope, cwd, env)
79
- if (!existsSync(file)) return {}
80
- try {
81
- const parsed = JSON.parse(readFileSync(file, 'utf8')) as LockFile
82
- return parsed && typeof parsed === 'object' ? parsed : {}
83
- } catch {
84
- return {}
85
- }
86
- }
87
-
88
- function conventionalSkillPath(
89
- scope: SkillScope,
90
- name: string,
91
- cwd: string,
92
- env: NodeJS.ProcessEnv,
93
- ): string {
94
- if (scope === 'project') return path.join(cwd, '.agents', 'skills', name)
95
- return path.join(accountHome(env), '.agents', 'skills', name)
96
- }
97
-
98
- function skillsFromLock(scope: SkillScope, cwd: string, env: NodeJS.ProcessEnv): NativeSkill[] {
99
- const lock = readLock(scope, cwd, env)
100
- return Object.entries(lock.skills ?? {}).flatMap(([name, entry]): NativeSkill[] => {
101
- if (entry === null || typeof entry !== 'object') return []
102
- return [
103
- {
104
- name,
105
- scope,
106
- path:
107
- typeof entry.skillPath === 'string' && entry.skillPath !== ''
108
- ? entry.skillPath
109
- : conventionalSkillPath(scope, name, cwd, env),
110
- source: typeof entry.source === 'string' ? entry.source : null,
111
- sourceType: typeof entry.sourceType === 'string' ? entry.sourceType : null,
112
- sourceUrl: typeof entry.sourceUrl === 'string' ? entry.sourceUrl : null,
113
- ref: typeof entry.ref === 'string' ? entry.ref : null,
114
- },
115
- ]
116
- })
117
- }
118
-
119
- function run(args: string[], options: { cwd: string; env: NodeJS.ProcessEnv }): Promise<number> {
120
- return new Promise((resolve) => {
121
- const launch = npxLaunch(args, options)
122
- const child = spawn(launch.file, launch.args, launch.options)
123
- child.on('error', () => resolve(1))
124
- child.on('exit', (code) => resolve(code ?? 1))
125
- })
126
- }
127
-
128
- /** argv for `npx`, including the pinned installer spec. */
129
- export function skillsAddArgv(options: SkillsAddOptions): string[] {
130
- const args = ['-y', SKILLS_INSTALLER_SPEC, 'add', options.source, '--skill', options.skill]
131
- if (options.scope === 'global') args.push('--global')
132
- // An explicit scope is the unattended contract. Native `--yes` keeps all
133
- // remaining installer prompts non-interactive after the scope is chosen.
134
- if (options.scope !== undefined) args.push('--yes')
135
- return args
136
- }
137
-
138
- /** argv for uninstalling one skill in one installer scope. */
139
- export function skillsRemoveArgv(options: SkillsRemoveOptions): string[] {
140
- const args = ['-y', SKILLS_INSTALLER_SPEC, 'remove', options.skill]
141
- if (options.scope === 'global') args.push('--global')
142
- args.push('--yes')
143
- return args
144
- }
145
-
146
- /** The only process/filesystem adapter Notifai needs for the external installer. */
147
- export const nativeSkills: NativeSkills = {
148
- async add(options) {
149
- return run(skillsAddArgv(options), { cwd: options.cwd, env: options.env })
150
- },
151
-
152
- async remove(options) {
153
- return run(skillsRemoveArgv(options), { cwd: options.cwd, env: options.env })
154
- },
155
-
156
- async list(scope, cwd, env) {
157
- // Presence is already on disk. `npx skills list` takes seconds and cannot
158
- // change whether the notifai skill is installed — the lock file is what
159
- // the installer itself consults.
160
- return { skills: skillsFromLock(scope, cwd, env) }
161
- },
162
- }
@@ -1,25 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { describe, expect, it } from 'vitest'
3
-
4
- const publicReadme = readFileSync(new URL('../../../README.md', import.meta.url), 'utf8')
5
- const cliReadme = readFileSync(new URL('../README.md', import.meta.url), 'utf8')
6
-
7
- describe('public onboarding docs', () => {
8
- it('installs the CLI before the first quick-start invocation', () => {
9
- const using = publicReadme.slice(publicReadme.indexOf('## Using it'))
10
- const install = using.indexOf('npm install -g @raidiant/notifai')
11
- const firstInvocation = using.search(/^notifai(?:\s|$)/m)
12
-
13
- expect(install).toBeGreaterThan(0)
14
- expect(firstInvocation).toBeGreaterThan(install)
15
- expect(using.slice(install, firstInvocation)).toContain('@raidiant/notifai')
16
- })
17
-
18
- it('states the active Android external-test boundary without promising a public release', () => {
19
- const harnesses = cliReadme.slice(cliReadme.indexOf('## Agent harnesses'))
20
-
21
- expect(harnesses).toMatch(/Android Companion App is active[\s\S]*external testing/i)
22
- expect(harnesses).toMatch(/Firebase App Distribution/i)
23
- expect(harnesses).toMatch(/not a\s+public release or a Google Play promise/i)
24
- })
25
- })