@raidiant/notifai 0.1.7 → 0.2.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/README.md +10 -3
- package/dist/atomic-file.d.ts +12 -0
- package/dist/atomic-file.js +55 -0
- package/dist/atomic-file.js.map +1 -0
- package/dist/client.d.ts +2 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/commands.d.ts +46 -15
- package/dist/commands.js +760 -248
- package/dist/commands.js.map +1 -1
- package/dist/hooks.d.ts +27 -12
- package/dist/hooks.js +519 -155
- package/dist/hooks.js.map +1 -1
- package/dist/install-hooks.d.ts +8 -4
- package/dist/install-hooks.js +45 -64
- package/dist/install-hooks.js.map +1 -1
- package/dist/main.js +80 -36
- package/dist/main.js.map +1 -1
- package/dist/native-skills.d.ts +31 -0
- package/dist/native-skills.js +117 -0
- package/dist/native-skills.js.map +1 -0
- package/dist/opencode-plugin.d.ts +1 -0
- package/dist/opencode-plugin.js +37 -4
- package/dist/opencode-plugin.js.map +1 -1
- package/dist/send.d.ts +19 -29
- package/dist/send.js +62 -57
- package/dist/send.js.map +1 -1
- package/package.json +5 -5
- package/src/atomic-file.ts +73 -0
- package/src/client.ts +3 -0
- package/src/commands.test.ts +1036 -72
- package/src/commands.ts +923 -261
- package/src/config.test.ts +68 -6
- package/src/hooks.test.ts +500 -9
- package/src/hooks.ts +624 -173
- package/src/install-hooks.test.ts +44 -16
- package/src/install-hooks.ts +50 -68
- package/src/main.ts +95 -41
- package/src/native-skills.ts +177 -0
- package/src/opencode-plugin.ts +38 -5
- package/src/send.ts +82 -60
- package/src/skill.test.ts +43 -0
package/README.md
CHANGED
|
@@ -15,6 +15,12 @@ notifai init
|
|
|
15
15
|
`init` walks the setup one step at a time and tells you the single next
|
|
16
16
|
thing to do. Run it again after each step; it works out what remains.
|
|
17
17
|
|
|
18
|
+
When `--skills` is selected at a human terminal, `init` runs the native
|
|
19
|
+
`npx skills` flow so that flow can ask whether the skill belongs to the
|
|
20
|
+
project or the machine. An unattended caller must select one explicitly:
|
|
21
|
+
`notifai init --skills --skills-scope project` or
|
|
22
|
+
`notifai init --skills --skills-scope global`.
|
|
23
|
+
|
|
18
24
|
## Telling you something happened
|
|
19
25
|
|
|
20
26
|
```sh
|
|
@@ -29,7 +35,7 @@ banner and is shown in the companion app for when you sit down.
|
|
|
29
35
|
## Asking you a question
|
|
30
36
|
|
|
31
37
|
```sh
|
|
32
|
-
notifai ask "Deploy the migration to production?" --choice
|
|
38
|
+
notifai ask "Deploy the migration to production?" --choice Yes --choice No
|
|
33
39
|
```
|
|
34
40
|
|
|
35
41
|
The agent registers the question, ends its turn, and your answer comes
|
|
@@ -62,7 +68,8 @@ notifai doctor
|
|
|
62
68
|
```
|
|
63
69
|
|
|
64
70
|
Reports every part of the setup and names where to start if something is
|
|
65
|
-
wrong.
|
|
71
|
+
wrong. Any `FAIL` line makes the command exit nonzero; informational `--` lines
|
|
72
|
+
do not. `--json` emits the same result with an explicit `exit_code`.
|
|
66
73
|
|
|
67
74
|
## Reference
|
|
68
75
|
|
|
@@ -71,6 +78,6 @@ Everything useful is possible non-interactively, so an agent never
|
|
|
71
78
|
reaches a prompt and hangs.
|
|
72
79
|
|
|
73
80
|
Source, issues and the security policy:
|
|
74
|
-
<https://github.com/
|
|
81
|
+
<https://github.com/Raidiant-io/notifai>
|
|
75
82
|
|
|
76
83
|
Apache-2.0.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface AtomicWriteOptions {
|
|
2
|
+
/** Mode for a newly created file. Existing regular files keep their mode. */
|
|
3
|
+
mode?: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Replace one regular file without exposing a truncated intermediate state.
|
|
7
|
+
*
|
|
8
|
+
* The temporary file is a unique sibling, so rename is atomic on every
|
|
9
|
+
* supported filesystem. The contents are flushed before the rename, and a
|
|
10
|
+
* symlink target is refused instead of silently writing through it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function atomicWriteFileSync(file: string, contents: string, options?: AtomicWriteOptions): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { closeSync, fsyncSync, lstatSync, mkdirSync, openSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Replace one regular file without exposing a truncated intermediate state.
|
|
6
|
+
*
|
|
7
|
+
* The temporary file is a unique sibling, so rename is atomic on every
|
|
8
|
+
* supported filesystem. The contents are flushed before the rename, and a
|
|
9
|
+
* symlink target is refused instead of silently writing through it.
|
|
10
|
+
*/
|
|
11
|
+
export function atomicWriteFileSync(file, contents, options = {}) {
|
|
12
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
13
|
+
const mode = targetMode(file, options.mode ?? 0o600);
|
|
14
|
+
const temp = path.join(path.dirname(file), `.${path.basename(file)}.notifai-${process.pid}-${randomBytes(6).toString('hex')}.tmp`);
|
|
15
|
+
let handle;
|
|
16
|
+
try {
|
|
17
|
+
handle = openSync(temp, 'wx', mode);
|
|
18
|
+
writeFileSync(handle, contents);
|
|
19
|
+
fsyncSync(handle);
|
|
20
|
+
closeSync(handle);
|
|
21
|
+
handle = undefined;
|
|
22
|
+
renameSync(temp, file);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (handle !== undefined)
|
|
26
|
+
closeSync(handle);
|
|
27
|
+
try {
|
|
28
|
+
unlinkSync(temp);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Preserve the original error; the temp may not have been created.
|
|
32
|
+
}
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Mode to preserve, or the mode for a new file. Refuses a non-regular target. */
|
|
37
|
+
function targetMode(file, fallback) {
|
|
38
|
+
let stat;
|
|
39
|
+
try {
|
|
40
|
+
stat = lstatSync(file);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code === 'ENOENT')
|
|
44
|
+
return fallback;
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
if (stat.isSymbolicLink()) {
|
|
48
|
+
throw new Error(`${file} is a symlink; refusing to write through it. Replace it with a regular file, ` +
|
|
49
|
+
'or use a different state directory.');
|
|
50
|
+
}
|
|
51
|
+
if (!stat.isFile())
|
|
52
|
+
throw new Error(`${file} is not a regular file; refusing to replace it.`);
|
|
53
|
+
return stat.mode & 0o777;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=atomic-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file.js","sourceRoot":"","sources":["../src/atomic-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,UAAU,EACV,UAAU,EACV,aAAa,GACd,MAAM,SAAS,CAAA;AAChB,OAAO,IAAI,MAAM,WAAW,CAAA;AAO5B;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,QAAgB,EAChB,UAA8B,EAAE;IAEhC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAClB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CACvF,CAAA;IACD,IAAI,MAA0B,CAAA;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACnC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,SAAS,CAAC,MAAM,CAAC,CAAA;QACjB,SAAS,CAAC,MAAM,CAAC,CAAA;QACjB,MAAM,GAAG,SAAS,CAAA;QAClB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS,CAAC,MAAM,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,IAAI,IAAI,CAAA;IACR,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAA;QACrE,MAAM,GAAG,CAAA;IACX,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,+EAA+E;YACpF,qCAAqC,CACxC,CAAA;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iDAAiD,CAAC,CAAA;IAC7F,OAAO,IAAI,CAAC,IAAI,GAAG,KAAK,CAAA;AAC1B,CAAC"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BeginPairingResponse, CapabilityDocument, CreateMediaUploadRequestT, CreateMediaUploadResponse, EvidenceSnapshot, ListDevicesResponse, ListRepliesResponse, Platform, PollPairingResponse, SubmissionReceipt, SubmitNotificationRequestT } from '@raidiant/notifai-protocol';
|
|
1
|
+
import type { AccountAccessResponse, BeginPairingResponse, CapabilityDocument, CreateMediaUploadRequestT, CreateMediaUploadResponse, EvidenceSnapshot, ListDevicesResponse, ListRepliesResponse, Platform, PollPairingResponse, SubmissionReceipt, SubmitNotificationRequestT } from '@raidiant/notifai-protocol';
|
|
2
2
|
export declare class ApiCallError extends Error {
|
|
3
3
|
status: number;
|
|
4
4
|
code: string;
|
|
@@ -15,6 +15,7 @@ export interface ApiClient {
|
|
|
15
15
|
poll_verifier_hash: string;
|
|
16
16
|
}): Promise<BeginPairingResponse>;
|
|
17
17
|
pollPairing(pairingId: string, pollVerifier: string): Promise<PollPairingResponse>;
|
|
18
|
+
accessStatus(): Promise<AccountAccessResponse>;
|
|
18
19
|
listDevices(): Promise<ListDevicesResponse>;
|
|
19
20
|
capabilities(platform?: Platform): Promise<CapabilityDocument>;
|
|
20
21
|
submit(body: SubmitNotificationRequestT, waitSeconds: number): Promise<SubmissionReceipt>;
|
package/dist/client.js
CHANGED
|
@@ -78,6 +78,7 @@ export function createClient(baseUrl, bearer, options = {}) {
|
|
|
78
78
|
return {
|
|
79
79
|
beginPairing: (body) => call('POST', '/api/v1/pairings', body),
|
|
80
80
|
pollPairing: (pairingId, pollVerifier) => call('POST', `/api/v1/pairings/${pairingId}/poll`, { poll_verifier: pollVerifier }),
|
|
81
|
+
accessStatus: () => call('GET', '/api/v1/account/access'),
|
|
81
82
|
listDevices: () => call('GET', '/api/v1/devices'),
|
|
82
83
|
capabilities: (platform = 'ios') => call('GET', `/api/v1/capabilities/${platform}`),
|
|
83
84
|
submit: (body, waitSeconds) => call('POST', `/api/v1/notifications?wait_seconds=${waitSeconds}`, body, waitSeconds),
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/commands.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { type ListRepliesResponse, type Platform, type ReplyView } from '@raidiant/notifai-protocol';
|
|
1
|
+
import { type ListRepliesResponse, type Platform, type QuestionT, type ReplyView } from '@raidiant/notifai-protocol';
|
|
2
2
|
import { type ApiClient, type ClientOptions } from './client.js';
|
|
3
3
|
import type { CredentialStore } from './credentials.js';
|
|
4
4
|
import { type Readiness } from './readiness.js';
|
|
5
|
+
import { type HookHarness } from './hooks.js';
|
|
5
6
|
import { type SendFlags } from './send.js';
|
|
7
|
+
import type { NativeSkills, SkillScope } from './native-skills.js';
|
|
6
8
|
export interface CommandIo {
|
|
7
9
|
out(line: string): void;
|
|
8
10
|
err(line: string): void;
|
|
@@ -46,6 +48,8 @@ export interface CommandDeps {
|
|
|
46
48
|
sleep?: (milliseconds: number) => Promise<void>;
|
|
47
49
|
/** Test seam for the OS idle probe; production shells out to the platform. */
|
|
48
50
|
idleSeconds?: () => number | null;
|
|
51
|
+
/** Test seam and production adapter for the external native skills installer. */
|
|
52
|
+
nativeSkills?: NativeSkills;
|
|
49
53
|
}
|
|
50
54
|
export declare const EXIT: {
|
|
51
55
|
readonly ok: 0;
|
|
@@ -64,6 +68,10 @@ export declare function logoutCommand(deps: CommandDeps): number;
|
|
|
64
68
|
export declare function authStatusCommand(deps: CommandDeps, flags: {
|
|
65
69
|
json?: boolean;
|
|
66
70
|
}): number;
|
|
71
|
+
/** Show the server's account access decision without attempting a product mutation. */
|
|
72
|
+
export declare function accessStatusCommand(deps: CommandDeps, flags: {
|
|
73
|
+
json?: boolean;
|
|
74
|
+
}): Promise<number>;
|
|
67
75
|
export declare function devicesCommand(deps: CommandDeps, flags: {
|
|
68
76
|
json?: boolean;
|
|
69
77
|
}): Promise<number>;
|
|
@@ -80,10 +88,11 @@ export declare function sendCommand(deps: CommandDeps, flags: SendFlags & {
|
|
|
80
88
|
idempotencyKey?: string;
|
|
81
89
|
baseUrl?: string;
|
|
82
90
|
}): Promise<number>;
|
|
83
|
-
export declare function repliesCommand(deps: CommandDeps,
|
|
91
|
+
export declare function repliesCommand(deps: CommandDeps, requestedId: string | undefined, flags: {
|
|
84
92
|
wait?: number;
|
|
85
93
|
after?: number;
|
|
86
94
|
json?: boolean;
|
|
95
|
+
pending?: boolean;
|
|
87
96
|
}): Promise<number>;
|
|
88
97
|
interface ReplyWaitOptions {
|
|
89
98
|
timeoutSeconds: number;
|
|
@@ -103,16 +112,15 @@ interface ReplyWaitResult {
|
|
|
103
112
|
/** Loop over server-capped long polls until a reply arrives or the caller's deadline passes. */
|
|
104
113
|
export declare function waitForReply(client: ApiClient, requestId: string, options: ReplyWaitOptions): Promise<ReplyWaitResult>;
|
|
105
114
|
/**
|
|
106
|
-
* The
|
|
115
|
+
* The correction note for a wait that saw more than one answer.
|
|
107
116
|
*
|
|
108
|
-
* A
|
|
109
|
-
* answer
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* answer between the first reply landing and its retirement arriving.
|
|
117
|
+
* A later reply that conflicts with an earlier one is a correction, so the
|
|
118
|
+
* latest answer is the one that counts. The server retires the question on
|
|
119
|
+
* the other devices the moment one answers, which makes this rare; it is
|
|
120
|
+
* still reachable, because a device can answer between the first reply
|
|
121
|
+
* landing and its retirement arriving.
|
|
114
122
|
*
|
|
115
|
-
* Ordered by seq, so `replies
|
|
123
|
+
* Ordered by seq, so `replies.at(-1)` is the answer to act on.
|
|
116
124
|
*/
|
|
117
125
|
export declare function contradictingAnswer(replies: ReplyView[]): string | null;
|
|
118
126
|
export declare function statusCommand(deps: CommandDeps, requestId: string, flags: {
|
|
@@ -129,7 +137,7 @@ export type HookEvent = (typeof HOOK_EVENTS)[number];
|
|
|
129
137
|
* throws, or that blocks past the harness's timeout, degrades the agent for a
|
|
130
138
|
* feature the user only asked to make it more convenient.
|
|
131
139
|
*/
|
|
132
|
-
export declare function hookRunCommand(deps: CommandDeps, event: string, readStdin: () => Promise<string>, harness?:
|
|
140
|
+
export declare function hookRunCommand(deps: CommandDeps, event: string, readStdin: () => Promise<string>, harness?: HookHarness): Promise<number>;
|
|
133
141
|
/**
|
|
134
142
|
* What went wrong, in terms of what to do about it.
|
|
135
143
|
*
|
|
@@ -146,16 +154,35 @@ export declare function hookRunCommand(deps: CommandDeps, event: string, readStd
|
|
|
146
154
|
*/
|
|
147
155
|
export declare function describeHookFailure(err: unknown): string[];
|
|
148
156
|
export interface AskFlags {
|
|
149
|
-
choice?: string
|
|
157
|
+
choice?: string[];
|
|
158
|
+
/** The single question is multi-select: several answers may be chosen. */
|
|
159
|
+
multi?: boolean;
|
|
160
|
+
/** Long-form markdown context; shown in the app, never on the banner. */
|
|
161
|
+
detail?: string;
|
|
162
|
+
/** Raw JSON for a multi-question form; replaces the positional question. */
|
|
163
|
+
form?: string;
|
|
150
164
|
session?: string;
|
|
151
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Turn ask input into the question set that will ride the push. Everything is
|
|
168
|
+
* validated here, at registration, because the push happens inside a hook
|
|
169
|
+
* where a rejection becomes a stderr note the agent never reads.
|
|
170
|
+
*/
|
|
171
|
+
export declare function buildQuestions(flags: AskFlags, question: string | undefined): {
|
|
172
|
+
ok: true;
|
|
173
|
+
questions: QuestionT[];
|
|
174
|
+
detail?: string;
|
|
175
|
+
} | {
|
|
176
|
+
ok: false;
|
|
177
|
+
error: string;
|
|
178
|
+
};
|
|
152
179
|
/**
|
|
153
180
|
* Registers a question for turn-end routing under the user's presence config.
|
|
154
181
|
* Returns immediately so the agent can ask in prose and end its turn. With the
|
|
155
182
|
* default presence gate, recent keyboard or mouse activity keeps it local;
|
|
156
183
|
* `require_idle = false` intentionally permits a push while the user is active.
|
|
157
184
|
*/
|
|
158
|
-
export declare function askCommand(deps: CommandDeps, question: string, flags: AskFlags): number;
|
|
185
|
+
export declare function askCommand(deps: CommandDeps, question: string | undefined, flags: AskFlags): number;
|
|
159
186
|
/** Retire a question so a late answer is rejected rather than silently lost. */
|
|
160
187
|
export declare function closeCommand(deps: CommandDeps, requestId: string): Promise<number>;
|
|
161
188
|
export interface HooksInstallFlags {
|
|
@@ -182,7 +209,7 @@ export declare function configSetCommand(deps: CommandDeps, key: string, rawValu
|
|
|
182
209
|
* 1.5.x, `owner/repo@name` selects a skill; a Git ref belongs after `#`.
|
|
183
210
|
* Keep this immutable and public because the command is printed to users.
|
|
184
211
|
*/
|
|
185
|
-
export declare const SKILLS_SOURCE = "
|
|
212
|
+
export declare const SKILLS_SOURCE = "Raidiant-io/notifai#v0.2.0";
|
|
186
213
|
/** Derive a contract-valid project slug from a directory name. */
|
|
187
214
|
export declare function projectSlugFrom(name: string): string;
|
|
188
215
|
export interface InitFlags {
|
|
@@ -194,6 +221,8 @@ export interface InitFlags {
|
|
|
194
221
|
* never spawn npx against the network by default.
|
|
195
222
|
*/
|
|
196
223
|
skills?: boolean;
|
|
224
|
+
/** Scope selected by an unattended caller; humans choose inside npx skills. */
|
|
225
|
+
skillsScope?: SkillScope;
|
|
197
226
|
/** Same tri-state, for the harness hooks. */
|
|
198
227
|
hooks?: boolean;
|
|
199
228
|
}
|
|
@@ -223,7 +252,9 @@ export declare function initCommand(deps: CommandDeps, flags: InitFlags): Promis
|
|
|
223
252
|
* `unknown`, which is the honest answer and keeps a network outage from
|
|
224
253
|
* looking like a broken install.
|
|
225
254
|
*/
|
|
226
|
-
export declare function assessReadiness(deps: CommandDeps
|
|
255
|
+
export declare function assessReadiness(deps: CommandDeps, options?: {
|
|
256
|
+
skillScope?: SkillScope;
|
|
257
|
+
}): Promise<Readiness>;
|
|
227
258
|
export declare function doctorCommand(deps: CommandDeps, flags: {
|
|
228
259
|
json?: boolean;
|
|
229
260
|
}): Promise<number>;
|