@poodle64/librarian 2026.9.22 → 2026.9.24
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 +11 -2
- package/dist/chat.svelte.d.ts +14 -5
- package/dist/chat.svelte.js +26 -12
- package/dist/components/agent-transcript/agent-transcript.svelte +5 -3
- package/dist/components/agent-transcript/agent-transcript.svelte.d.ts +4 -2
- package/dist/components/agent-transcript/index.d.ts +1 -1
- package/dist/components/conversation/conversation.svelte +45 -26
- package/dist/components/conversation/conversation.svelte.d.ts +10 -0
- package/dist/transcript.svelte.d.ts +3 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -179,6 +179,8 @@ on it fires once and never again.
|
|
|
179
179
|
| The empty state | `welcome` and up to three `examples` |
|
|
180
180
|
| What this surface covers | `scope`: one statement per room, in the host's own words. Rendered above the first turn and folded to a line once the conversation starts |
|
|
181
181
|
| The words themselves | `copy`: a partial of `LibrarianCopy`. Every component resolves it itself, so overriding one line does not mean restating the rest |
|
|
182
|
+
| An answer its own way | `turn`: a snippet given each turn's `AgentTranscriptProps` in place of `AgentTranscript`. Render your own from the parts, or `AgentTranscript` inside your own to add to it |
|
|
183
|
+
| What leads a conversation | `lead`: a snippet inside the scroll, under the opening and the scope, so a tall one scrolls with the conversation instead of taking its height |
|
|
182
184
|
|
|
183
185
|
Nothing here fetches on its own behalf. The library's document read is
|
|
184
186
|
authenticated, and a package that called it directly would be reaching past
|
|
@@ -243,6 +245,13 @@ the room's routes, and the components bound to it:
|
|
|
243
245
|
|
|
244
246
|
`chat.list()` reads the list once; after that it follows every answer.
|
|
245
247
|
|
|
248
|
+
A turn the host asks as a `kind` (`chat.ask(question, 'briefing')`, from
|
|
249
|
+
`Composer`'s `onbriefing`) goes to the route as `client.ask()`'s `kind`, comes
|
|
250
|
+
back on `StoredTurn.kind`, and carries whatever `new Chat(transport, {
|
|
251
|
+
artefact })` says that kind opens, on a live turn and a reopened one alike:
|
|
252
|
+
`{ title: 'Briefing', isAnswer: true }` cards it and opens its prose in the
|
|
253
|
+
column. `again()` asks it as the same kind.
|
|
254
|
+
|
|
246
255
|
The transport is the app's own client over its routes, and the shapes are
|
|
247
256
|
the routes' own bodies (`ConversationSummary`, `ConversationRead`,
|
|
248
257
|
`StoredTurn`, `Quota`), so the stamped slice returns them as they are and
|
|
@@ -568,6 +577,6 @@ Where Playwright's own Chromium will not start (NixOS), name one that does:
|
|
|
568
577
|
1. Change a component; bump `version` in `package.json` (CalVer).
|
|
569
578
|
2. `pnpm build`, which runs `svelte-package` then `publint`.
|
|
570
579
|
3. Commit, tag `librarian-v<version>`, push the tag.
|
|
571
|
-
4. `.github/workflows/publish.yaml` runs on that push and publishes through
|
|
572
|
-
npm's trusted publisher. Watch it: `gh run list --workflow=publish.yaml`,
|
|
580
|
+
4. `.github/workflows/publish-kit-typescript.yaml` (repo root) runs on that push and publishes through
|
|
581
|
+
npm's trusted publisher. Watch it: `gh run list -R radar-hooves/app-factory --workflow=publish-kit-typescript.yaml`,
|
|
573
582
|
then `npm view @poodle64/librarian version`.
|
package/dist/chat.svelte.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { type AgentEvent } from './client';
|
|
23
23
|
import type { Citation } from './citations';
|
|
24
|
-
import { type Turn } from './transcript.svelte';
|
|
24
|
+
import { type Artefact, type Turn } from './transcript.svelte';
|
|
25
25
|
/** One conversation in the list. */
|
|
26
26
|
export interface ConversationSummary {
|
|
27
27
|
/** The agent's own session id: what resumes it, what names it in the address. */
|
|
@@ -41,6 +41,8 @@ export interface StoredTurn {
|
|
|
41
41
|
/** ISO 8601, when it was asked. */
|
|
42
42
|
at?: string | null;
|
|
43
43
|
citations?: Citation[];
|
|
44
|
+
/** What the host asked for, when it was not a plain question. */
|
|
45
|
+
kind?: string | null;
|
|
44
46
|
}
|
|
45
47
|
/** A conversation reopened. */
|
|
46
48
|
export interface ConversationRead extends ConversationSummary {
|
|
@@ -69,6 +71,8 @@ export interface AskRequest {
|
|
|
69
71
|
/** The conversation this carries on; null starts one. */
|
|
70
72
|
resume: string | null;
|
|
71
73
|
signal: AbortSignal;
|
|
74
|
+
/** What the host asked for, when it is not a plain question: `client.ask()`'s `kind`. */
|
|
75
|
+
kind?: string;
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
78
|
* A room's routes, as the host's own client reaches them. Every method but
|
|
@@ -119,6 +123,10 @@ export interface ChatOptions {
|
|
|
119
123
|
pollMs?: number;
|
|
120
124
|
/** How often a closed job is asked whether it carries on. */
|
|
121
125
|
rewatchMs?: number;
|
|
126
|
+
/** What a turn asked as `kind` produces for the reader to open, in the
|
|
127
|
+
* host's words (a briefing: `{ title, isAnswer: true }`), on a turn asked
|
|
128
|
+
* here and on one read back alike. None for a plain question. */
|
|
129
|
+
artefact?: (kind: string) => Artefact | undefined;
|
|
122
130
|
}
|
|
123
131
|
export declare class Chat {
|
|
124
132
|
#private;
|
|
@@ -162,11 +170,12 @@ export declare class Chat {
|
|
|
162
170
|
* from an effect, as `open` is. */
|
|
163
171
|
new(): void;
|
|
164
172
|
/**
|
|
165
|
-
* Ask `question`, or what is in the box
|
|
166
|
-
*
|
|
167
|
-
*
|
|
173
|
+
* Ask `question`, or what is in the box, as a `kind` of turn when it is not
|
|
174
|
+
* a plain question. Resolves once the turn settles: true if it was asked,
|
|
175
|
+
* false if it was refused, here or by the server, in which case typed words
|
|
176
|
+
* go back into the box.
|
|
168
177
|
*/
|
|
169
|
-
ask(question?: string): Promise<boolean>;
|
|
178
|
+
ask(question?: string, kind?: string): Promise<boolean>;
|
|
170
179
|
/** The last question again, as a new turn: the conversation is append-only,
|
|
171
180
|
* because the agent's transcript is. */
|
|
172
181
|
again(): Promise<boolean>;
|
package/dist/chat.svelte.js
CHANGED
|
@@ -48,6 +48,7 @@ export class Chat {
|
|
|
48
48
|
#job = null;
|
|
49
49
|
#pollMs;
|
|
50
50
|
#rewatchMs;
|
|
51
|
+
#artefact;
|
|
51
52
|
#turns = $state([]);
|
|
52
53
|
#version = $state(0);
|
|
53
54
|
#running = $state(false);
|
|
@@ -71,6 +72,7 @@ export class Chat {
|
|
|
71
72
|
this.#room = transport;
|
|
72
73
|
this.#pollMs = options.pollMs ?? 5000;
|
|
73
74
|
this.#rewatchMs = options.rewatchMs ?? 2000;
|
|
75
|
+
this.#artefact = options.artefact;
|
|
74
76
|
}
|
|
75
77
|
/** Every turn, in order. A live one grows in place; key on `version`. */
|
|
76
78
|
get turns() {
|
|
@@ -142,11 +144,12 @@ export class Chat {
|
|
|
142
144
|
});
|
|
143
145
|
}
|
|
144
146
|
/**
|
|
145
|
-
* Ask `question`, or what is in the box
|
|
146
|
-
*
|
|
147
|
-
*
|
|
147
|
+
* Ask `question`, or what is in the box, as a `kind` of turn when it is not
|
|
148
|
+
* a plain question. Resolves once the turn settles: true if it was asked,
|
|
149
|
+
* false if it was refused, here or by the server, in which case typed words
|
|
150
|
+
* go back into the box.
|
|
148
151
|
*/
|
|
149
|
-
async ask(question) {
|
|
152
|
+
async ask(question, kind) {
|
|
150
153
|
const typed = question === undefined;
|
|
151
154
|
const text = (question ?? this.draft).trim();
|
|
152
155
|
if (!text)
|
|
@@ -160,13 +163,13 @@ export class Chat {
|
|
|
160
163
|
this.draft = '';
|
|
161
164
|
this.files = [];
|
|
162
165
|
}
|
|
163
|
-
return this.#ask(text, files, typed);
|
|
166
|
+
return this.#ask(text, files, typed, kind);
|
|
164
167
|
}
|
|
165
168
|
/** The last question again, as a new turn: the conversation is append-only,
|
|
166
169
|
* because the agent's transcript is. */
|
|
167
170
|
again() {
|
|
168
|
-
const last = this.turns.at(-1)
|
|
169
|
-
return last ? this.ask(last) : Promise.resolve(false);
|
|
171
|
+
const last = this.turns.at(-1);
|
|
172
|
+
return last?.question ? this.ask(last.question, last.kind) : Promise.resolve(false);
|
|
170
173
|
}
|
|
171
174
|
/** Stop the answer being written, wherever it is being written. */
|
|
172
175
|
async stop() {
|
|
@@ -298,7 +301,7 @@ export class Chat {
|
|
|
298
301
|
this.answering = null;
|
|
299
302
|
this.waiting = false;
|
|
300
303
|
}
|
|
301
|
-
async #ask(text, files, typed) {
|
|
304
|
+
async #ask(text, files, typed, kind) {
|
|
302
305
|
const room = this.#room;
|
|
303
306
|
const mine = this.#generation;
|
|
304
307
|
const stream = { controller: new AbortController(), stopWanted: false };
|
|
@@ -310,7 +313,9 @@ export class Chat {
|
|
|
310
313
|
blocks: [],
|
|
311
314
|
outcome: null,
|
|
312
315
|
citations: [],
|
|
313
|
-
suggestions: []
|
|
316
|
+
suggestions: [],
|
|
317
|
+
kind,
|
|
318
|
+
artefact: this.#card(kind)
|
|
314
319
|
});
|
|
315
320
|
const live = this.#turns[this.#turns.length - 1];
|
|
316
321
|
const state = foldState();
|
|
@@ -323,7 +328,8 @@ export class Chat {
|
|
|
323
328
|
question: text,
|
|
324
329
|
files,
|
|
325
330
|
resume: this.conversationId,
|
|
326
|
-
signal: stream.controller.signal
|
|
331
|
+
signal: stream.controller.signal,
|
|
332
|
+
kind
|
|
327
333
|
})) {
|
|
328
334
|
const named = event.type === 'system' && event.subtype === 'init' ? event.session_id : undefined;
|
|
329
335
|
if (stream.stopWanted) {
|
|
@@ -400,6 +406,10 @@ export class Chat {
|
|
|
400
406
|
this.#finish();
|
|
401
407
|
return true;
|
|
402
408
|
}
|
|
409
|
+
/** What a turn of `kind` opens, if the host says it opens anything. */
|
|
410
|
+
#card(kind) {
|
|
411
|
+
return kind ? this.#artefact?.(kind) : undefined;
|
|
412
|
+
}
|
|
403
413
|
/** A turn this page streamed has settled, one way or another. */
|
|
404
414
|
#finish() {
|
|
405
415
|
this.#stream = null;
|
|
@@ -415,7 +425,10 @@ export class Chat {
|
|
|
415
425
|
* read again until it settles. */
|
|
416
426
|
#show(read, mine) {
|
|
417
427
|
clearTimeout(this.#poll);
|
|
418
|
-
const turns = read.turns.map((stored, index) =>
|
|
428
|
+
const turns = read.turns.map((stored, index) => ({
|
|
429
|
+
...storedTurn(read.id, index, stored),
|
|
430
|
+
artefact: this.#card(stored.kind)
|
|
431
|
+
}));
|
|
419
432
|
this.#held = new Set(turns.map((t) => t.id));
|
|
420
433
|
const since = epoch(read.answering_since);
|
|
421
434
|
if (since !== null) {
|
|
@@ -537,7 +550,8 @@ function storedTurn(conversation, index, stored) {
|
|
|
537
550
|
at: epoch(stored.at) ?? undefined,
|
|
538
551
|
blocks: stored.answer ? [{ kind: 'text', index: 0, text: stored.answer }] : [],
|
|
539
552
|
outcome: null,
|
|
540
|
-
citations: stored.citations ?? []
|
|
553
|
+
citations: stored.citations ?? [],
|
|
554
|
+
kind: stored.kind ?? undefined
|
|
541
555
|
};
|
|
542
556
|
}
|
|
543
557
|
function epoch(value) {
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
import Markdown from '../markdown/markdown.svelte';
|
|
42
42
|
import SourceList from '../source-list/source-list.svelte';
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
/** Everything one turn renders from: what `Conversation` hands a host's
|
|
45
|
+
* own `turn` snippet, so it can render this component or its own. */
|
|
46
|
+
export interface AgentTranscriptProps {
|
|
45
47
|
question: string;
|
|
46
48
|
blocks: Block[];
|
|
47
49
|
outcome: Outcome | null;
|
|
@@ -109,7 +111,7 @@
|
|
|
109
111
|
waiting = false,
|
|
110
112
|
answering,
|
|
111
113
|
onmark
|
|
112
|
-
}:
|
|
114
|
+
}: AgentTranscriptProps = $props();
|
|
113
115
|
|
|
114
116
|
// The prose IS the artefact: it reads in the column, and the transcript
|
|
115
117
|
// shows the card alone.
|
|
@@ -393,7 +395,7 @@
|
|
|
393
395
|
|
|
394
396
|
.ds-lib-ask {
|
|
395
397
|
display: flex;
|
|
396
|
-
|
|
398
|
+
width: 100%;
|
|
397
399
|
flex-direction: column;
|
|
398
400
|
align-items: flex-end;
|
|
399
401
|
gap: 0.25rem;
|
|
@@ -2,7 +2,9 @@ import { type Artefact, type Block, type DescribeTool, type Outcome } from '../.
|
|
|
2
2
|
import { type Citation } from '../../citations';
|
|
3
3
|
import { type LibrarianCopy } from '../../copy';
|
|
4
4
|
import type { Verdict } from '../../chat.svelte';
|
|
5
|
-
|
|
5
|
+
/** Everything one turn renders from: what `Conversation` hands a host's
|
|
6
|
+
* own `turn` snippet, so it can render this component or its own. */
|
|
7
|
+
export interface AgentTranscriptProps {
|
|
6
8
|
question: string;
|
|
7
9
|
blocks: Block[];
|
|
8
10
|
outcome: Outcome | null;
|
|
@@ -48,6 +50,6 @@ interface Props {
|
|
|
48
50
|
* control that records nothing is worse than none. */
|
|
49
51
|
onmark?: (verdict: Verdict) => Promise<boolean>;
|
|
50
52
|
}
|
|
51
|
-
declare const AgentTranscript: import("svelte").Component<
|
|
53
|
+
declare const AgentTranscript: import("svelte").Component<AgentTranscriptProps, {}, "">;
|
|
52
54
|
type AgentTranscript = ReturnType<typeof AgentTranscript>;
|
|
53
55
|
export default AgentTranscript;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default as AgentTranscript } from './agent-transcript.svelte';
|
|
1
|
+
export { default as AgentTranscript, type AgentTranscriptProps } from './agent-transcript.svelte';
|
|
2
2
|
export { default } from './agent-transcript.svelte';
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
import type { Citation, LoadDocument } from '../../citations';
|
|
17
17
|
import { DEFAULT_PERSONA, personaName, resolveCopy, type LibrarianCopy } from '../../copy';
|
|
18
18
|
import { FollowScroll } from '../../follow-scroll.svelte';
|
|
19
|
-
import AgentTranscript
|
|
19
|
+
import AgentTranscript, {
|
|
20
|
+
type AgentTranscriptProps
|
|
21
|
+
} from '../agent-transcript/agent-transcript.svelte';
|
|
20
22
|
import ArtefactPane from '../artefact-pane/artefact-pane.svelte';
|
|
21
23
|
import DocumentPane from '../document-pane/document-pane.svelte';
|
|
22
24
|
import ScopeStatement from '../scope-statement/scope-statement.svelte';
|
|
@@ -81,6 +83,15 @@
|
|
|
81
83
|
* pane narrows it too — a composer the host places outside slides
|
|
82
84
|
* under the pane the moment one opens. */
|
|
83
85
|
composer?: Snippet;
|
|
86
|
+
/** Renders each turn in place of `AgentTranscript`, given the props it
|
|
87
|
+
* would have taken: a host that presents an answer its own way (its
|
|
88
|
+
* prose, its citation marks, its links) renders its own, and one that
|
|
89
|
+
* only adds to it renders `AgentTranscript` inside it. */
|
|
90
|
+
turn?: Snippet<[AgentTranscriptProps]>;
|
|
91
|
+
/** Before the first turn, inside the scroll and under the opening and
|
|
92
|
+
* the scope: what the host shows ahead of a question, which scrolls
|
|
93
|
+
* with the conversation rather than taking its height. */
|
|
94
|
+
lead?: Snippet;
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
let {
|
|
@@ -104,7 +115,9 @@
|
|
|
104
115
|
showing,
|
|
105
116
|
describeTool,
|
|
106
117
|
collectionNames = new Set(),
|
|
107
|
-
composer
|
|
118
|
+
composer,
|
|
119
|
+
turn: presentTurn,
|
|
120
|
+
lead
|
|
108
121
|
}: Props = $props();
|
|
109
122
|
|
|
110
123
|
// Resolved ONCE, here, and handed down whole: every child takes `copy` and
|
|
@@ -267,32 +280,38 @@
|
|
|
267
280
|
<ScopeStatement statement={scope} expanded={turns.length === 0} copy={words} />
|
|
268
281
|
{/if}
|
|
269
282
|
|
|
283
|
+
{@render lead?.()}
|
|
284
|
+
|
|
270
285
|
{#each turns as turn, index (turn.id)}
|
|
271
286
|
{@const last = index === turns.length - 1}
|
|
272
|
-
|
|
273
|
-
question
|
|
274
|
-
blocks
|
|
275
|
-
outcome
|
|
276
|
-
running
|
|
277
|
-
waiting
|
|
278
|
-
answering
|
|
279
|
-
citations
|
|
280
|
-
suggestions
|
|
281
|
-
|
|
282
|
-
copy
|
|
283
|
-
name
|
|
284
|
-
at
|
|
285
|
-
artefact
|
|
286
|
-
artefactOpen
|
|
287
|
-
onopenartefact
|
|
288
|
-
|
|
289
|
-
oncite
|
|
290
|
-
onregenerate
|
|
291
|
-
onsuggest
|
|
292
|
-
onmark
|
|
293
|
-
? (verdict) => onmark(turn, verdict)
|
|
294
|
-
|
|
295
|
-
|
|
287
|
+
{@const props = {
|
|
288
|
+
question: turn.question,
|
|
289
|
+
blocks: turn.blocks,
|
|
290
|
+
outcome: turn.outcome,
|
|
291
|
+
running: running && last,
|
|
292
|
+
waiting: waiting && last,
|
|
293
|
+
answering: last ? (answering ?? undefined) : undefined,
|
|
294
|
+
citations: turn.citations ?? [],
|
|
295
|
+
suggestions: turn.suggestions ?? [],
|
|
296
|
+
collectionNames,
|
|
297
|
+
copy: words,
|
|
298
|
+
name: who,
|
|
299
|
+
at: turn.at ?? stamps[turn.id],
|
|
300
|
+
artefact: turn.artefact,
|
|
301
|
+
artefactOpen: isShowing(turn),
|
|
302
|
+
onopenartefact: opener(turn),
|
|
303
|
+
describeTool,
|
|
304
|
+
oncite: oncite || loadDocument ? cite : undefined,
|
|
305
|
+
onregenerate: last && !running ? onregenerate : undefined,
|
|
306
|
+
onsuggest: last && !running ? onsuggest : undefined,
|
|
307
|
+
onmark:
|
|
308
|
+
last && !running && onmark ? (verdict: Verdict) => onmark(turn, verdict) : undefined
|
|
309
|
+
} satisfies AgentTranscriptProps}
|
|
310
|
+
{#if presentTurn}
|
|
311
|
+
{@render presentTurn(props)}
|
|
312
|
+
{:else}
|
|
313
|
+
<AgentTranscript {...props} />
|
|
314
|
+
{/if}
|
|
296
315
|
{/each}
|
|
297
316
|
</div>
|
|
298
317
|
</div>
|
|
@@ -3,6 +3,7 @@ import type { DescribeTool, Turn } from '../../transcript.svelte';
|
|
|
3
3
|
import type { Verdict } from '../../chat.svelte';
|
|
4
4
|
import type { Citation, LoadDocument } from '../../citations';
|
|
5
5
|
import { type LibrarianCopy } from '../../copy';
|
|
6
|
+
import { type AgentTranscriptProps } from '../agent-transcript/agent-transcript.svelte';
|
|
6
7
|
interface Props {
|
|
7
8
|
turns: Turn[];
|
|
8
9
|
running: boolean;
|
|
@@ -58,6 +59,15 @@ interface Props {
|
|
|
58
59
|
* pane narrows it too — a composer the host places outside slides
|
|
59
60
|
* under the pane the moment one opens. */
|
|
60
61
|
composer?: Snippet;
|
|
62
|
+
/** Renders each turn in place of `AgentTranscript`, given the props it
|
|
63
|
+
* would have taken: a host that presents an answer its own way (its
|
|
64
|
+
* prose, its citation marks, its links) renders its own, and one that
|
|
65
|
+
* only adds to it renders `AgentTranscript` inside it. */
|
|
66
|
+
turn?: Snippet<[AgentTranscriptProps]>;
|
|
67
|
+
/** Before the first turn, inside the scroll and under the opening and
|
|
68
|
+
* the scope: what the host shows ahead of a question, which scrolls
|
|
69
|
+
* with the conversation rather than taking its height. */
|
|
70
|
+
lead?: Snippet;
|
|
61
71
|
}
|
|
62
72
|
declare const Conversation: import("svelte").Component<Props, {}, "">;
|
|
63
73
|
type Conversation = ReturnType<typeof Conversation>;
|
|
@@ -205,6 +205,9 @@ export interface Turn {
|
|
|
205
205
|
/** Something this turn produced for the reader to open, carded under the
|
|
206
206
|
* answer once the turn settles. */
|
|
207
207
|
artefact?: Artefact;
|
|
208
|
+
/** What the host asked for when this was not a plain question
|
|
209
|
+
* (`'briefing'`), in its own word, as `client.ask()` sent it. */
|
|
210
|
+
kind?: string;
|
|
208
211
|
}
|
|
209
212
|
/** A turn's artefact, in the host's own words. */
|
|
210
213
|
export interface Artefact {
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poodle64/librarian",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.24",
|
|
4
4
|
"description": "An agent's conversation surface as a consumable Svelte 5 package: the stream client, transcript state and self-styling chat components (transcript, composer, markdown) every household app renders instead of rebuilding, speaking as whichever persona the app names.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/radar-hooves/
|
|
9
|
+
"url": "git+https://github.com/radar-hooves/app-factory.git",
|
|
10
|
+
"directory": "kits/typescript/packages/librarian"
|
|
10
11
|
},
|
|
11
12
|
"publishConfig": {
|
|
12
13
|
"registry": "https://registry.npmjs.org",
|
|
13
14
|
"access": "public",
|
|
14
|
-
"provenance":
|
|
15
|
+
"provenance": true
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"dist"
|