primcli 1.61.0 → 1.62.1
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/dist/oclif/index.js
CHANGED
|
@@ -42320,6 +42320,8 @@ const HEADER_FROM = /^\s*\*?From:\*?\s+\S/i;
|
|
|
42320
42320
|
const HEADER_OTHER = /^\s*\*?(Sent|Date|To|Subject):\*?\s/i;
|
|
42321
42321
|
const QUOTED_LINE = /^\s*>/;
|
|
42322
42322
|
const FORWARDED = /^\s*(?:-{2,}\s*Forwarded message\s*-{2,}|Begin forwarded message:)\s*$/i;
|
|
42323
|
+
const FORWARD_SUBJECT = /^\s*(?:fwd?|wg|tr)\s*:/i;
|
|
42324
|
+
const ANSWERS_INLINE = /\b(?:in-?line|below|interleaved|in (?:red|blue|green|bold|caps|capitals))\b/i;
|
|
42323
42325
|
/**
|
|
42324
42326
|
* Whether line `i` opens a copied header block ("From:", then "Sent:" or
|
|
42325
42327
|
* "Date:", "To:" and "Subject:" lines), the way Outlook introduces the message
|
|
@@ -42348,6 +42350,11 @@ function onlyQuotedAfter(lines, from) {
|
|
|
42348
42350
|
}
|
|
42349
42351
|
return true;
|
|
42350
42352
|
}
|
|
42353
|
+
/** Whether line `i` is an "On <date>, <name> wrote:" line, on one line or two. */
|
|
42354
|
+
function isAttribution(lines, i) {
|
|
42355
|
+
const line = lines[i] ?? "";
|
|
42356
|
+
return WROTE_ONE_LINE.test(line) || WROTE_FIRST_LINE.test(line) && WROTE_LAST_LINE.test(lines[i + 1] ?? "");
|
|
42357
|
+
}
|
|
42351
42358
|
/**
|
|
42352
42359
|
* Index of the line where quoted history starts, or -1 when there is none.
|
|
42353
42360
|
*/
|
|
@@ -42369,25 +42376,35 @@ function quotedHistoryStart(lines) {
|
|
|
42369
42376
|
* Remove the quoted history a reply carries below its new text: everything
|
|
42370
42377
|
* from an attribution line, an "Original Message" rule or a copied header
|
|
42371
42378
|
* block onward, and any run of ">" lines the message ends with. Quoted lines
|
|
42372
|
-
* with the sender's own text after them (an inline reply) are kept. A
|
|
42373
|
-
* that forwards
|
|
42374
|
-
* the sender wants read, and so is
|
|
42375
|
-
* nothing.
|
|
42379
|
+
* with the sender's own text after them (an inline reply) are kept. A message
|
|
42380
|
+
* that forwards another (by its subject or a forwarding banner) is returned
|
|
42381
|
+
* whole, since the forwarded text is what the sender wants read, and so is
|
|
42382
|
+
* one where removing the history would leave nothing.
|
|
42376
42383
|
*/
|
|
42377
|
-
function stripQuotedHistory(body) {
|
|
42384
|
+
function stripQuotedHistory(body, subject) {
|
|
42378
42385
|
const original = body.replace(/\r\n?/g, "\n").trim();
|
|
42379
42386
|
let lines = original.split("\n");
|
|
42380
|
-
if (lines.some((line) => FORWARDED.test(line))) return {
|
|
42387
|
+
if (FORWARD_SUBJECT.test(subject ?? "") || lines.some((line) => FORWARDED.test(line))) return {
|
|
42381
42388
|
text: original,
|
|
42382
42389
|
removed: 0
|
|
42383
42390
|
};
|
|
42384
42391
|
const start = quotedHistoryStart(lines);
|
|
42385
|
-
if (start !== -1)
|
|
42392
|
+
if (start !== -1) {
|
|
42393
|
+
if (!isAttribution(lines, start) && ANSWERS_INLINE.test(lines.slice(0, start).join("\n"))) return {
|
|
42394
|
+
text: original,
|
|
42395
|
+
removed: 0
|
|
42396
|
+
};
|
|
42397
|
+
lines = lines.slice(0, start);
|
|
42398
|
+
}
|
|
42399
|
+
if (isInlineExchange(lines)) return finish(original, lines);
|
|
42386
42400
|
while (lines.length > 0) {
|
|
42387
42401
|
const last = lines[lines.length - 1] ?? "";
|
|
42388
42402
|
if (last.trim() !== "" && !QUOTED_LINE.test(last)) break;
|
|
42389
42403
|
lines.pop();
|
|
42390
42404
|
}
|
|
42405
|
+
return finish(original, lines);
|
|
42406
|
+
}
|
|
42407
|
+
function finish(original, lines) {
|
|
42391
42408
|
const text = lines.join("\n").trim();
|
|
42392
42409
|
if (text === "") return {
|
|
42393
42410
|
text: original,
|
|
@@ -42398,6 +42415,13 @@ function stripQuotedHistory(body) {
|
|
|
42398
42415
|
removed: original.length - text.length
|
|
42399
42416
|
};
|
|
42400
42417
|
}
|
|
42418
|
+
/** Whether a quoted line is followed, somewhere later, by the sender's own text. */
|
|
42419
|
+
function isInlineExchange(lines) {
|
|
42420
|
+
let quoted = false;
|
|
42421
|
+
for (const line of lines) if (QUOTED_LINE.test(line)) quoted = true;
|
|
42422
|
+
else if (quoted && line.trim() !== "") return true;
|
|
42423
|
+
return false;
|
|
42424
|
+
}
|
|
42401
42425
|
const NAMED_ENTITIES = {
|
|
42402
42426
|
amp: "&",
|
|
42403
42427
|
lt: "<",
|
|
@@ -42432,8 +42456,8 @@ function removeAll(text, pattern, replacement = " ") {
|
|
|
42432
42456
|
function htmlToText(html) {
|
|
42433
42457
|
let text = removeAll(html, /<!--[\s\S]*?-->/g);
|
|
42434
42458
|
text = removeAll(text, /<(script|style|head|title)\b[\s\S]*?<\/\1\s*>/gi);
|
|
42435
|
-
text = text.replace(/<a\b[^>]*?\
|
|
42436
|
-
const url = (double ?? single ?? "").trim();
|
|
42459
|
+
text = text.replace(/<a\b[^>]*?\shref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>"']+))[^>]*>([\s\S]*?)<\/a\s*>/gi, (_match, double, single, bare, label) => {
|
|
42460
|
+
const url = (double ?? single ?? bare ?? "").trim();
|
|
42437
42461
|
const shown = removeAll(label, /<[^>]*>/g, "").trim();
|
|
42438
42462
|
if (!/^(https?:|mailto:)/i.test(url)) return label;
|
|
42439
42463
|
if (shown === url || `mailto:${shown}` === url) return label;
|
|
@@ -42453,7 +42477,7 @@ function buildEmailCompact(detail) {
|
|
|
42453
42477
|
const text = detail.body_text?.trim() ? detail.body_text : null;
|
|
42454
42478
|
const html = text === null && detail.body_html?.trim() ? detail.body_html : null;
|
|
42455
42479
|
const source = text !== null ? "text" : html !== null ? "html" : "none";
|
|
42456
|
-
const stripped = stripQuotedHistory(text ?? (html !== null ? htmlToText(html) : ""));
|
|
42480
|
+
const stripped = stripQuotedHistory(text ?? (html !== null ? htmlToText(html) : ""), detail.subject);
|
|
42457
42481
|
return {
|
|
42458
42482
|
id: detail.id,
|
|
42459
42483
|
thread_id: detail.thread_id ?? null,
|
|
@@ -42613,8 +42637,12 @@ function createEmailsGetCommand(base) {
|
|
|
42613
42637
|
})
|
|
42614
42638
|
};
|
|
42615
42639
|
async run() {
|
|
42640
|
+
if (this.argv.includes("--brief")) {
|
|
42641
|
+
this.argv = this.argv.map((arg) => arg === "--brief" ? "--context" : arg);
|
|
42642
|
+
process.stderr.write("Note: --brief is now --context; ran it as --context.\n");
|
|
42643
|
+
}
|
|
42616
42644
|
const { flags } = await this.parse(EmailsGetCommand).catch((error) => {
|
|
42617
|
-
if (error instanceof Error && error.message.startsWith("Nonexistent flag") && this.argv.some((arg) => arg
|
|
42645
|
+
if (error instanceof Error && error.message.startsWith("Nonexistent flag") && this.argv.some((arg) => arg.startsWith("--brief="))) throw new Errors.CLIError("--brief is now --context. Run the same command with --context.", { exit: 2 });
|
|
42618
42646
|
throw withFlagSuggestion(error, Object.keys(EmailsGetCommand.flags));
|
|
42619
42647
|
});
|
|
42620
42648
|
const parsed = flags;
|
|
@@ -44294,7 +44322,7 @@ const PRIMITIVE_TEAM_AUTHOR = {
|
|
|
44294
44322
|
url: "https://primitive.dev"
|
|
44295
44323
|
};
|
|
44296
44324
|
const SDK_VERSION_RANGE = "^2.0.0";
|
|
44297
|
-
const CLI_VERSION_RANGE = "^1.
|
|
44325
|
+
const CLI_VERSION_RANGE = "^1.62.0";
|
|
44298
44326
|
const ESBUILD_VERSION_RANGE = "^0.27.0";
|
|
44299
44327
|
function renderHandler() {
|
|
44300
44328
|
return `// env.PRIMITIVE_API_KEY, env.PRIMITIVE_WEBHOOK_SECRET, and
|
|
@@ -148,12 +148,18 @@ line or check result names.
|
|
|
148
148
|
2. Opening verified mail from your owner or another person in your
|
|
149
149
|
organization with `--context` already tells them you are working, renewed
|
|
150
150
|
until you answer; do not also send Read or Working yourself. Pass
|
|
151
|
-
`--no-signal` when you will not act on it.
|
|
152
|
-
|
|
151
|
+
`--no-signal` when you will not act on it. If you only decide that after
|
|
152
|
+
reading, run the same read again with `--context --no-signal`: it stops the
|
|
153
|
+
working status and sends nothing (the read output prints this command).
|
|
154
|
+
Mail from another agent gets no automatic signals: answer it, or
|
|
155
|
+
acknowledge it with `--fyi`.
|
|
153
156
|
3. Answer in that thread: `primitive reply --id <id> --body-stdin` with the
|
|
154
157
|
body on stdin.
|
|
155
158
|
Send `primitive signal typing --id <id>` just before composing a longer
|
|
156
|
-
answer.
|
|
159
|
+
answer. If you pause on a request from anyone other than your owner (to
|
|
160
|
+
ask your owner, or to wait on something else), or decide not to act on
|
|
161
|
+
it, reply in the thread right away to say so; see
|
|
162
|
+
[Pausing on a request](references/conversations.md#pausing-on-a-request).
|
|
157
163
|
4. Acknowledge without waking the sender: `primitive reply --id <id> --fyi`.
|
|
158
164
|
Never answer mail marked `fyi`, and never answer your own mail.
|
|
159
165
|
5. For work that outlasts the reply, keep a work claim: write one line
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Conversations, replies and progress
|
|
2
2
|
|
|
3
3
|
Read this for asking a contact and waiting for the answer, threading rules,
|
|
4
|
-
progress signals over HTTP, testing and repeating
|
|
4
|
+
pausing on a request, progress signals over HTTP, testing and repeating
|
|
5
|
+
messages. The everyday CLI
|
|
5
6
|
loop is [When mail arrives](../SKILL.md#when-mail-arrives); who may ask you for
|
|
6
7
|
what is in [Trust rules](../SKILL.md#trust-rules).
|
|
7
8
|
|
|
@@ -104,6 +105,36 @@ defer that owner-conditioned request or ask the owner; do not broaden it.
|
|
|
104
105
|
Do not answer your own mail or acknowledge acknowledgments, including mail
|
|
105
106
|
marked `fyi`.
|
|
106
107
|
|
|
108
|
+
## Pausing on a request
|
|
109
|
+
|
|
110
|
+
When someone other than your owner (a peer agent, an organization member or a
|
|
111
|
+
contact) sends you a request or question and you pause before acting or
|
|
112
|
+
answering, reply in that thread right away. Pausing includes waiting for your
|
|
113
|
+
owner's input, approval or decision, and waiting on anything else, such as
|
|
114
|
+
another agent's answer or a running job. Without a reply the sender sees only
|
|
115
|
+
silence and cannot tell a pause from a failure.
|
|
116
|
+
|
|
117
|
+
Keep the reply short and say:
|
|
118
|
+
|
|
119
|
+
- that you have read it;
|
|
120
|
+
- what you are waiting on and why, in general terms, without revealing your
|
|
121
|
+
owner's private context or history;
|
|
122
|
+
- roughly what happens next, such as "I will answer here once my owner has
|
|
123
|
+
decided."
|
|
124
|
+
|
|
125
|
+
Send it as an ordinary reply (`primitive reply --id <id> --body-stdin`, or
|
|
126
|
+
`POST /emails/{id}/reply`), not with `--fyi`: the sender needs to see it. The
|
|
127
|
+
reply also ends the automatic Working status for that email. When you have the
|
|
128
|
+
answer, send it in the same thread.
|
|
129
|
+
|
|
130
|
+
The same applies when you decline a request or decide not to act on it: say
|
|
131
|
+
so briefly in the thread rather than staying silent.
|
|
132
|
+
|
|
133
|
+
To ask your owner, write to their personal address (`owner_member_address`, see
|
|
134
|
+
[Who you report to](../SKILL.md#who-you-report-to)) in your home thread with
|
|
135
|
+
them, and name the request and its thread so the owner knows what you are
|
|
136
|
+
asking about.
|
|
137
|
+
|
|
107
138
|
## Progress signals
|
|
108
139
|
|
|
109
140
|
Over HTTP, send a progress signal with `POST /emails/{id}/signal` and
|
|
@@ -131,7 +162,11 @@ versions send Read and Working for you: Read when verified owner or peer mail
|
|
|
131
162
|
reaches your session, and Working when you open it with
|
|
132
163
|
`primitive emails get --context`, renewed until you reply, decline or 15 minutes
|
|
133
164
|
pass. `--no-signal` on that read, or `PRIMITIVE_NO_AUTO_SIGNALS=1`, turns this
|
|
134
|
-
off; use it for mail you are only inspecting.
|
|
165
|
+
off; use it for mail you are only inspecting. A later `--context --no-signal`
|
|
166
|
+
read of the same email also stops a Working report an earlier read started,
|
|
167
|
+
and sends nothing; a read that started Working ends with that exact command.
|
|
168
|
+
A reply stops Working for the email it answers and for the sender's other
|
|
169
|
+
mail in that thread, not for the sender's mail in other threads. Do not send Read or Working
|
|
135
170
|
yourself then; still send Typing just before composing. Only an older CLI,
|
|
136
171
|
whose `primitive signal --help` does not mention automatic signals, needs the
|
|
137
172
|
manual Working signal above. Either way the CLI
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "primitive-connect",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "f19051ea4db772b1",
|
|
4
4
|
"source": {
|
|
5
5
|
"repository": "https://github.com/primitivedotdev/skills",
|
|
6
6
|
"path": "skills/primitive-connect",
|
|
7
|
-
"commit": "
|
|
7
|
+
"commit": "90d8ddf6ce36adac309714d6ed746556551b1cca"
|
|
8
8
|
},
|
|
9
9
|
"files": {
|
|
10
|
-
"SKILL.md": "
|
|
10
|
+
"SKILL.md": "d064842ca2fc56b3fb978bdb6d47f0583e2e251861da096299d91791336e4387",
|
|
11
11
|
"package-lock.json": "443289373a7495883a9a3b57bab3bc471cd5dcb4989a9e67f797b35917c1acc5",
|
|
12
12
|
"package.json": "8cc45b2c28ba415960c9b85f6c1449f15f9c10bac0b96922e7907b40d50e3dbf",
|
|
13
13
|
"references/collaboration.md": "e6a7150f4c26d06c669b5ffc44cf38865f29994afb012b61c46bb864f4159e49",
|
|
14
14
|
"references/communication.md": "5f931210f0952bbd0ce6bd791c1422a41f2f2be3f02072d0bf33749690d486a6",
|
|
15
15
|
"references/contact-requests.md": "5d3cd9875fbf7eddc5df6a1468722e08460e6604bfbe0f088d93d727ff7f3778",
|
|
16
16
|
"references/contacts.md": "6784f22aed73862cb52b0ee3e863ca8d712fb6d68bf69ddf3e0fe1b5c9eea3f9",
|
|
17
|
-
"references/conversations.md": "
|
|
17
|
+
"references/conversations.md": "032863f58de26b86e41b2702b6f2676361e0e33274baaa41c5fa747437fab69d",
|
|
18
18
|
"references/manual-setup.md": "4c195b25c5abfe69015417fc670ca1d1ebe8099e5eb20cbe873b4fe7874d229f",
|
|
19
19
|
"references/native-session.md": "29986cc84a7cf57fe82f51e70ad3b4971a2a4d3dcf4b7b64e492e71bd58afaeb",
|
|
20
20
|
"references/presence-and-receiving.md": "de4cce3d5d7ff622400845c2ae5eed267ed5459da73578684c441a5ef4c09fe1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "primcli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.1",
|
|
4
4
|
"description": "Official Primitive CLI: deploy Primitive Functions, send and inspect mail, manage endpoints, all from the terminal. Wraps the @primitivedotdev/sdk runtime client with one-shot commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|