crewly 1.20.290 → 1.20.292
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/config/domain-sops/expert-distillation.sop.md +45 -45
- package/config/skills/agent/core/calendar-create/SKILL.md +1 -1
- package/config/skills/agent/core/calendar-list/SKILL.md +1 -1
- package/config/skills/agent/core/docs-comment/SKILL.md +5 -3
- package/config/skills/agent/core/docs-read/SKILL.md +4 -2
- package/config/skills/agent/core/docs-write/SKILL.md +4 -2
- package/config/skills/agent/core/drive-read/SKILL.md +4 -2
- package/config/skills/agent/core/drive-search/SKILL.md +4 -2
- package/config/skills/agent/core/drive-upload/SKILL.md +4 -2
- package/config/skills/agent/core/gmail-read/SKILL.md +1 -1
- package/config/skills/agent/core/gmail-search/SKILL.md +5 -4
- package/config/skills/agent/core/gmail-send/SKILL.md +2 -2
- package/config/skills/agent/core/google-connect/SKILL.md +17 -14
- package/config/skills/agent/core/google-connect/execute.sh +25 -8
- package/config/skills/agent/core/sheets-read/SKILL.md +4 -2
- package/config/skills/agent/core/sheets-write/SKILL.md +4 -2
- package/config/skills/agent/core/slides-create/SKILL.md +4 -2
- package/config/skills/agent/core/slides-read/SKILL.md +4 -2
- package/dist/backend/backend/src/constants.d.ts +24 -9
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +41 -26
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/bundle/bundle.controller.js +1 -1
- package/dist/backend/backend/src/controllers/bundle/bundle.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google-connect-card.d.ts +36 -19
- package/dist/backend/backend/src/controllers/google/google-connect-card.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google-connect-card.js +57 -40
- package/dist/backend/backend/src/controllers/google/google-connect-card.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts +3 -2
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.js +36 -10
- package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
- package/dist/backend/backend/src/services/bundle/bundle-apply.service.js +45 -45
- package/dist/backend/backend/src/services/bundle/bundle-apply.service.js.map +1 -1
- package/dist/backend/backend/src/services/bundle/bundle-placeholders.js +7 -7
- package/dist/backend/backend/src/services/bundle/bundle-placeholders.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +3 -3
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +19 -19
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +1 -1
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +1 -1
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts +17 -21
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js +34 -39
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js.map +1 -1
- package/dist/backend/backend/src/services/google/google-reauth.wiring.d.ts +6 -2
- package/dist/backend/backend/src/services/google/google-reauth.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-reauth.wiring.js +9 -4
- package/dist/backend/backend/src/services/google/google-reauth.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js +1 -1
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +2 -2
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.js +1 -1
- package/dist/backend/backend/src/services/onboarding/onboarding-checklist.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +36 -12
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-key.d.ts +12 -0
- package/dist/backend/backend/src/services/slack/slack-thread-key.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-key.js +20 -0
- package/dist/backend/backend/src/services/slack/slack-thread-key.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +2 -2
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts +3 -3
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js +7 -7
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-intake.service.d.ts +2 -2
- package/dist/backend/backend/src/services/v3/ticket-intake.service.js +1 -1
- package/dist/backend/backend/src/services/v3/ticket-review.service.js +5 -5
- package/dist/backend/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/dist/backend/backend/src/utils/incomplete-turn.utils.js +6 -6
- package/dist/backend/backend/src/utils/incomplete-turn.utils.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +24 -9
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +41 -26
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/bundle/bundle-apply.service.js +45 -45
- package/dist/cli/backend/src/services/bundle/bundle-apply.service.js.map +1 -1
- package/dist/cli/backend/src/services/bundle/bundle-placeholders.js +7 -7
- package/dist/cli/backend/src/services/bundle/bundle-placeholders.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +3 -3
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +19 -19
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +1 -1
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +1 -1
- package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.js +1 -1
- package/dist/cli/backend/src/services/onboarding/onboarding-checklist.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-key.d.ts +12 -0
- package/dist/cli/backend/src/services/slack/slack-thread-key.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-key.js +20 -0
- package/dist/cli/backend/src/services/slack/slack-thread-key.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +2 -2
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts +3 -3
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js +7 -7
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-intake.service.d.ts +2 -2
- package/dist/cli/backend/src/services/v3/ticket-intake.service.js +1 -1
- package/dist/cli/backend/src/services/v3/ticket-review.service.js +5 -5
- package/dist/cli/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/dist/cli/backend/src/utils/incomplete-turn.utils.js +6 -6
- package/dist/cli/backend/src/utils/incomplete-turn.utils.js.map +1 -1
- package/dist/cli/cli/src/commands/deploy-bundle.js +4 -4
- package/dist/cli/cli/src/commands/deploy-bundle.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +1 -1
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/package.json +1 -1
- package/packages/crewly-agent/src/runtime/reply-tool-calls.ts +0 -3
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
# SOP: Expert Mindset Distillation
|
|
1
|
+
# SOP: Expert Mindset Distillation
|
|
2
2
|
|
|
3
3
|
**Version:** 1.0.0
|
|
4
4
|
**Owner:** Product Team (Mia)
|
|
5
5
|
**Scope:** Crewly Pro Core Methodology
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
8
|
-
|
|
7
|
+
## 1. Objective
|
|
8
|
+
This SOP standardizes the "expert mindset distillation" process: turning unstructured material from famous people and experts into a structured `Expert Profile` (MD + JSON) that Crewly can use, so Agents get high-quality mindset injection.
|
|
9
9
|
|
|
10
|
-
## 2.
|
|
11
|
-
- **Primary Source:**
|
|
12
|
-
- **Secondary Source:**
|
|
10
|
+
## 2. Inputs
|
|
11
|
+
- **Primary Source:** the expert's books (PDF/EPUB), public interview recordings or transcripts (Markdown/TXT).
|
|
12
|
+
- **Secondary Source:** media analysis articles, Wikipedia, YouTube video transcripts.
|
|
13
13
|
- **Tools:**
|
|
14
|
-
- Teacher Model: Claude 3.5 Sonnet (
|
|
15
|
-
- Crewly Distiller CLI: `crewly-pro distill
|
|
14
|
+
- Teacher Model: Claude 3.5 Sonnet (preferred) or GPT-4o.
|
|
15
|
+
- Crewly Distiller CLI: `crewly-pro distill`.
|
|
16
16
|
|
|
17
|
-
## 3.
|
|
17
|
+
## 3. Phases
|
|
18
18
|
|
|
19
|
-
### Phase 1:
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
19
|
+
### Phase 1: Data Preprocessing
|
|
20
|
+
- **Task:** filter out irrelevant material (ads, small talk, repeated passages).
|
|
21
|
+
- **Standard:** keep only the core text that contains "decision logic", "values", "industry insights" and "language style".
|
|
22
|
+
- **Output:** the cleaned text file (`raw_distill_input.txt`).
|
|
23
23
|
|
|
24
|
-
### Phase 2:
|
|
25
|
-
-
|
|
24
|
+
### Phase 2: Mindset Extraction
|
|
25
|
+
- **Task:** run the Distillation Prompt with the Teacher Model.
|
|
26
26
|
- **Prompt:**
|
|
27
27
|
```markdown
|
|
28
28
|
# SYSTEM PROMPT: Expert Mindset Distiller
|
|
29
|
-
|
|
29
|
+
You are a top-tier "mindset modeling expert". Your goal is to analyze the provided expert material and extract the underlying "thinking software".
|
|
30
30
|
|
|
31
|
-
##
|
|
32
|
-
1. **Mental Models (
|
|
33
|
-
2. **Decision Logic
|
|
34
|
-
3. **Industry Insights
|
|
35
|
-
4. **Communication Style
|
|
31
|
+
## Dimensions to extract:
|
|
32
|
+
1. **Mental Models:** the core frameworks the expert uses often (e.g. first principles, the 80/20 rule).
|
|
33
|
+
2. **Decision Logic:** how the expert weighs risk, handles trade-offs, and evaluates short- vs long-term benefit.
|
|
34
|
+
3. **Industry Insights:** the expert's distinctive "counter-intuitive" views on a specific field.
|
|
35
|
+
4. **Communication Style:** filler words, signature phrases, the structure of their argumentation.
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
-
|
|
39
|
-
-
|
|
37
|
+
## Constraints:
|
|
38
|
+
- Describe from an analytical, calm third-person perspective; do not imitate their tone of voice.
|
|
39
|
+
- The extracted mental models must be "actionable", i.e. an Agent can cite them while executing tasks.
|
|
40
40
|
```
|
|
41
|
-
-
|
|
41
|
+
- **Output:** the expert mindset draft (`{expert-id}-draft.md`).
|
|
42
42
|
|
|
43
|
-
### Phase 3:
|
|
44
|
-
-
|
|
45
|
-
- **JSON
|
|
46
|
-
- **MD
|
|
43
|
+
### Phase 3: Formatting and JSON Metadata (Synthesis)
|
|
44
|
+
- **Task:** turn the draft into standard Markdown and generate the metadata JSON.
|
|
45
|
+
- **JSON spec:** see `config/experts/EXAMPLE.json`.
|
|
46
|
+
- **MD spec:** see `config/experts/EXAMPLE.md`.
|
|
47
47
|
|
|
48
|
-
### Phase 4: OSS/Pro
|
|
49
|
-
-
|
|
48
|
+
### Phase 4: OSS/Pro Boundary (Security & Packaging)
|
|
49
|
+
- **Task:** package according to the distribution channel.
|
|
50
50
|
- **OSS:**
|
|
51
|
-
-
|
|
52
|
-
-
|
|
51
|
+
- MD file only.
|
|
52
|
+
- Stored in `config/experts/`.
|
|
53
53
|
- **Pro:**
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
54
|
+
- MD + JSON.
|
|
55
|
+
- Includes a preset `intensity` value.
|
|
56
|
+
- Stored in `crewly-pro/data/experts/`.
|
|
57
|
+
- Must pass the `LicenseValidator` check.
|
|
58
58
|
|
|
59
|
-
### Phase 5:
|
|
60
|
-
- **Round 1 (Self):**
|
|
61
|
-
- **Round 2 (Peer):**
|
|
62
|
-
- **Round 3 (Test):**
|
|
59
|
+
### Phase 5: Quality Gates
|
|
60
|
+
- **Round 1 (Self):** the distiller checks that the logic is self-consistent.
|
|
61
|
+
- **Round 2 (Peer):** another PM or expert reviews whether the extracted models capture the essence.
|
|
62
|
+
- **Round 3 (Test):** inject the Profile into an Agent and run a prompt stress test on 3 standard tasks.
|
|
63
63
|
|
|
64
|
-
## 4.
|
|
64
|
+
## 4. Outputs
|
|
65
65
|
- `config/experts/{id}.md`
|
|
66
66
|
- `crewly-pro/data/experts/{id}.json` (Pro Only)
|
|
67
67
|
|
|
68
|
-
## 5.
|
|
69
|
-
- **Accuracy:**
|
|
70
|
-
- **Utility:** Agent
|
|
68
|
+
## 5. KPIs
|
|
69
|
+
- **Accuracy:** the distilled model accurately predicts the expert's decision tendencies in 80% of common business scenarios.
|
|
70
|
+
- **Utility:** after an Agent uses the template, its professional rating in the specific domain improves by ≥ 20%.
|
|
@@ -63,7 +63,7 @@ Missing `--summary` / `--start` / `--end` → `{"error":"Missing required parame
|
|
|
63
63
|
|
|
64
64
|
## Choosing a Google account
|
|
65
65
|
|
|
66
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
66
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
69
|
bash execute.sh --account work@company.com ...
|
|
@@ -59,7 +59,7 @@ when the owner has not connected Google Workspace.
|
|
|
59
59
|
|
|
60
60
|
## Choosing a Google account
|
|
61
61
|
|
|
62
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
62
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
bash execute.sh --account work@company.com ...
|
|
@@ -100,8 +100,10 @@ older connections do not include. When the output has
|
|
|
100
100
|
`"reconnectLinkSent":true`, the harness has already sent the owner a one-tap
|
|
101
101
|
reconnect card in Slack: tell them in one line what you will do once it is
|
|
102
102
|
granted, and retry when you get `[GOOGLE] Google Drive reconnected — retry your
|
|
103
|
-
comment.`
|
|
104
|
-
|
|
103
|
+
comment.` The card's link does not expire. If the owner says it did not work (or
|
|
104
|
+
there is no `reconnectLinkSent`), run `google-connect --product drive --resend` for a
|
|
105
|
+
fresh card, or give them https://crewlyai.com/portal/integrations/google?products=drive&auto=1
|
|
106
|
+
to open directly. Never send them to Crewly settings or the Connections page.
|
|
105
107
|
|
|
106
108
|
`{"success":false,"reason":"not_connected","hint":"…"}` (exit 1): Google
|
|
107
109
|
Drive is not connected. Use `google-connect --product drive` the same way.
|
|
@@ -115,7 +117,7 @@ wrong, or the account cannot see the document.
|
|
|
115
117
|
|
|
116
118
|
## Choosing a Google account
|
|
117
119
|
|
|
118
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
120
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
119
121
|
|
|
120
122
|
```bash
|
|
121
123
|
bash execute.sh list --doc 1AbC… --account work@company.com
|
|
@@ -45,13 +45,15 @@ bash execute.sh --id "https://docs.google.com/document/d/1AbC…/edit"
|
|
|
45
45
|
## Failures
|
|
46
46
|
|
|
47
47
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
48
|
-
when the owner has not connected Google Workspace
|
|
48
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
49
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
50
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
49
51
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
50
52
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
51
53
|
|
|
52
54
|
## Choosing a Google account
|
|
53
55
|
|
|
54
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
56
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
55
57
|
|
|
56
58
|
```bash
|
|
57
59
|
bash execute.sh --account work@company.com ...
|
|
@@ -50,13 +50,15 @@ re-connect Google Workspace once the scope is enabled".
|
|
|
50
50
|
## Failures
|
|
51
51
|
|
|
52
52
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
53
|
-
when the owner has not connected Google Workspace
|
|
53
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
54
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
55
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
54
56
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
55
57
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
56
58
|
|
|
57
59
|
## Choosing a Google account
|
|
58
60
|
|
|
59
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
61
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
60
62
|
|
|
61
63
|
```bash
|
|
62
64
|
bash execute.sh --account work@company.com ...
|
|
@@ -39,13 +39,15 @@ Files over 10 MB are refused with a `webViewLink` to open instead.
|
|
|
39
39
|
## Failures
|
|
40
40
|
|
|
41
41
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
42
|
-
when the owner has not connected Google Workspace
|
|
42
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
43
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
44
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
43
45
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
44
46
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
45
47
|
|
|
46
48
|
## Choosing a Google account
|
|
47
49
|
|
|
48
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
50
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
49
51
|
|
|
50
52
|
```bash
|
|
51
53
|
bash execute.sh --account work@company.com ...
|
|
@@ -41,13 +41,15 @@ else → `drive-read`.
|
|
|
41
41
|
## Failures
|
|
42
42
|
|
|
43
43
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
44
|
-
when the owner has not connected Google Workspace
|
|
44
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
45
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
46
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
45
47
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
46
48
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
47
49
|
|
|
48
50
|
## Choosing a Google account
|
|
49
51
|
|
|
50
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
52
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
51
53
|
|
|
52
54
|
```bash
|
|
53
55
|
bash execute.sh --account work@company.com ...
|
|
@@ -40,13 +40,15 @@ permissions are the owner's — this skill does not change sharing).
|
|
|
40
40
|
## Failures
|
|
41
41
|
|
|
42
42
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
43
|
-
when the owner has not connected Google Workspace
|
|
43
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
44
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
45
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
44
46
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
45
47
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
46
48
|
|
|
47
49
|
## Choosing a Google account
|
|
48
50
|
|
|
49
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
51
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
54
|
bash execute.sh --account work@company.com ...
|
|
@@ -62,7 +62,7 @@ with a 404 message when the id is unknown.
|
|
|
62
62
|
|
|
63
63
|
## Choosing a Google account
|
|
64
64
|
|
|
65
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
65
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
68
|
bash execute.sh --account work@company.com ...
|
|
@@ -33,7 +33,7 @@ execution:
|
|
|
33
33
|
# Gmail Search
|
|
34
34
|
|
|
35
35
|
Runs a Gmail search on the owner's mailbox and prints the hits. Uses the
|
|
36
|
-
Google Workspace connection the owner made
|
|
36
|
+
Google Workspace connection the owner made in Crewly;
|
|
37
37
|
the mail content goes straight from Google to this instance.
|
|
38
38
|
|
|
39
39
|
```bash
|
|
@@ -60,12 +60,13 @@ Use the `id` with `gmail-read` to get the body; `threadId` + `gmail-read`'s
|
|
|
60
60
|
## Failures
|
|
61
61
|
|
|
62
62
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` — the
|
|
63
|
-
owner has not connected Google Workspace yet;
|
|
64
|
-
|
|
63
|
+
owner has not connected Google Workspace yet; run the `google-connect` skill so
|
|
64
|
+
they get a one-tap card in Slack (manual fallback: https://crewlyai.com/portal/integrations/google; never
|
|
65
|
+
Crewly settings or the Connections page). Exit code 1.
|
|
65
66
|
|
|
66
67
|
## Choosing a Google account
|
|
67
68
|
|
|
68
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
69
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
69
70
|
|
|
70
71
|
```bash
|
|
71
72
|
bash execute.sh --account work@company.com ...
|
|
@@ -103,13 +103,13 @@ There is no output shape in which you have sent an email.
|
|
|
103
103
|
Missing `--to` / `--subject` / body → `{"error":"Missing required parameter: …"}` on stderr, exit 1, nothing sent.
|
|
104
104
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1) when the owner has not connected Google Workspace.
|
|
105
105
|
|
|
106
|
-
`{"success":false,"reason":"reauth_required","hint":"A reconnect link was sent to the owner in Slack. …","reconnectLinkSent":true}` (exit 1): the Gmail connection cannot save drafts yet (connections made before 2026-10-08 lack that permission). The harness has already sent the owner a one-tap reconnect card in Slack. Tell them in one line that you need them to tap it — do not
|
|
106
|
+
`{"success":false,"reason":"reauth_required","hint":"A reconnect link was sent to the owner in Slack. …","reconnectLinkSent":true}` (exit 1): the Gmail connection cannot save drafts yet (connections made before 2026-10-08 lack that permission). The harness has already sent the owner a one-tap reconnect card in Slack. Tell them in one line that you need them to tap it — do not send them to Crewly settings or Connections. The card's link does not expire; if they say it failed, run the `google-connect` skill for a fresh one, or give them https://crewlyai.com/portal/integrations/google. When it is done you get `[GOOGLE] Gmail reconnected — retry your draft.`; run the same command again.
|
|
107
107
|
|
|
108
108
|
`{"success":false,"reason":"not_connected",…,"reconnectLinkSent":true}` (exit 1): Gmail access expired or was revoked. Same as above: the owner already has the card; wait for `[GOOGLE] Gmail reconnected …` and retry.
|
|
109
109
|
|
|
110
110
|
## Choosing a Google account
|
|
111
111
|
|
|
112
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
112
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
113
113
|
|
|
114
114
|
```bash
|
|
115
115
|
bash execute.sh --account work@company.com ...
|
|
@@ -23,22 +23,25 @@ execution:
|
|
|
23
23
|
|
|
24
24
|
# Google Connect
|
|
25
25
|
|
|
26
|
-
When a Google skill answers `not_connected`, the owner has
|
|
27
|
-
product
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Run this instead. It posts a card with an **Add** button that only the
|
|
33
|
-
person who asked can see, backed by a single-use link.
|
|
26
|
+
When a Google skill answers `not_connected` or `reauth_required`, the owner has
|
|
27
|
+
to grant (or re-grant) a product. Do **not** improvise an authorization link:
|
|
28
|
+
never build one by hand and never paste one. Run this instead. It posts a card
|
|
29
|
+
with a button that only the person who asked can see; the button opens the
|
|
30
|
+
Crewly portal's Google page, so the link carries no credential and **never
|
|
31
|
+
expires**. The owner can tap it hours later, from a phone.
|
|
34
32
|
|
|
35
33
|
```bash
|
|
36
|
-
bash execute.sh --product gmail --channel <chat-channel-id>
|
|
34
|
+
bash execute.sh --product gmail [--channel <chat-channel-id>] [--account me@example.com]
|
|
37
35
|
```
|
|
38
36
|
|
|
39
|
-
`--channel` is the id in the `[CHAT:…]` header of the
|
|
40
|
-
answering.
|
|
37
|
+
- `--channel` is the id in the `[CHAT:…]` or `[SLACK-THREAD:…]` header of the
|
|
38
|
+
message you are answering. It is optional: without it, or if it cannot be
|
|
39
|
+
resolved, the card goes where you are working with the owner, else their DM.
|
|
40
|
+
- Every call posts a fresh card. If the owner says the last card did not work,
|
|
41
|
+
run it again (`--resend` is accepted to make that intent explicit).
|
|
42
|
+
- Never tell the owner to open Crewly settings or the Connections page — they
|
|
43
|
+
are usually on a phone and cannot reach it. If they cannot find the card, the
|
|
44
|
+
manual fallback is https://crewlyai.com/portal/integrations/google
|
|
41
45
|
|
|
42
|
-
After running it, say in one line that you have asked for access and what
|
|
43
|
-
|
|
44
|
-
to repeat.
|
|
46
|
+
After running it, say in one line that you have asked for access and what you
|
|
47
|
+
will do once it is granted. Do not repeat a link.
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
# google-connect — Ask the owner to authorize a Google product, in Slack
|
|
4
4
|
#
|
|
5
5
|
# Backed by POST /api/google/connect-card, which posts a Block Kit card whose
|
|
6
|
-
# button
|
|
7
|
-
#
|
|
6
|
+
# button opens the Cloud portal's Google page (no token in the link, and it
|
|
7
|
+
# never expires). Never build an authorization link by hand.
|
|
8
8
|
#
|
|
9
9
|
# Usage:
|
|
10
|
-
# bash execute.sh --product gmail --channel chat-abc123
|
|
10
|
+
# bash execute.sh --product gmail [--channel chat-abc123] [--account me@x.com] [--resend]
|
|
11
11
|
# =============================================================================
|
|
12
12
|
set -euo pipefail
|
|
13
13
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -16,32 +16,49 @@ source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
|
16
16
|
print_usage() {
|
|
17
17
|
cat <<'EOF_USAGE'
|
|
18
18
|
Usage:
|
|
19
|
-
bash execute.sh --product <gmail|calendar|drive> --channel <
|
|
19
|
+
bash execute.sh --product <gmail|calendar|drive> [--channel <id>] [--account <email>] [--resend]
|
|
20
20
|
|
|
21
21
|
Options:
|
|
22
22
|
--product Which Google product needs access (required)
|
|
23
|
-
--channel The
|
|
23
|
+
--channel The id in the [CHAT:...] / [SLACK-THREAD:...] header of the message you are
|
|
24
|
+
answering. Optional: without it (or if it cannot be resolved) the card goes
|
|
25
|
+
where you are working, else the owner's DM.
|
|
26
|
+
--account Google account to reconnect, when it matters
|
|
27
|
+
--resend The owner said the last card did not work; every call posts a fresh card
|
|
28
|
+
(accepted for clarity, the flag changes nothing)
|
|
24
29
|
EOF_USAGE
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
PRODUCT=""
|
|
28
33
|
CHANNEL=""
|
|
34
|
+
ACCOUNT=""
|
|
29
35
|
while [ $# -gt 0 ]; do
|
|
30
36
|
case "$1" in
|
|
31
37
|
--product) PRODUCT="${2:-}"; shift 2 ;;
|
|
32
38
|
--channel) CHANNEL="${2:-}"; shift 2 ;;
|
|
39
|
+
--account) ACCOUNT="${2:-}"; shift 2 ;;
|
|
40
|
+
--resend) shift ;;
|
|
33
41
|
-h|--help) print_usage; exit 0 ;;
|
|
34
42
|
*) echo "Unknown option: $1" >&2; print_usage >&2; exit 2 ;;
|
|
35
43
|
esac
|
|
36
44
|
done
|
|
37
45
|
|
|
38
|
-
if [ -z "$PRODUCT" ]
|
|
39
|
-
echo "
|
|
46
|
+
if [ -z "$PRODUCT" ]; then
|
|
47
|
+
echo "--product is required." >&2
|
|
40
48
|
print_usage >&2
|
|
41
49
|
exit 2
|
|
42
50
|
fi
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
# Values go into JSON by hand (no jq dependency): refuse anything that could break out.
|
|
53
|
+
for v in "$PRODUCT" "$CHANNEL" "$ACCOUNT"; do
|
|
54
|
+
case "$v" in
|
|
55
|
+
*[\"\\]*|*$'\n'*) echo "Arguments must not contain quotes, backslashes or newlines." >&2; exit 2 ;;
|
|
56
|
+
esac
|
|
57
|
+
done
|
|
58
|
+
BODY=$(printf '{"product":"%s"' "$PRODUCT")
|
|
59
|
+
[ -n "$CHANNEL" ] && BODY="${BODY},$(printf '"channelId":"%s"' "$CHANNEL")"
|
|
60
|
+
[ -n "$ACCOUNT" ] && BODY="${BODY},$(printf '"account":"%s"' "$ACCOUNT")"
|
|
61
|
+
BODY="${BODY}}"
|
|
45
62
|
RESPONSE=$(api_call POST "/google/connect-card" "$BODY" 2>&1) || {
|
|
46
63
|
echo "$RESPONSE" >&2
|
|
47
64
|
exit 1
|
|
@@ -48,13 +48,15 @@ come back as numbers, dates as the sheet's formatted string.
|
|
|
48
48
|
## Failures
|
|
49
49
|
|
|
50
50
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
51
|
-
when the owner has not connected Google Workspace
|
|
51
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
52
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
53
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
52
54
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
53
55
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
54
56
|
|
|
55
57
|
## Choosing a Google account
|
|
56
58
|
|
|
57
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
59
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
58
60
|
|
|
59
61
|
```bash
|
|
60
62
|
bash execute.sh --account work@company.com ...
|
|
@@ -51,13 +51,15 @@ the owner made outside Crewly needs the Sheets write scope (`403 google_error`).
|
|
|
51
51
|
## Failures
|
|
52
52
|
|
|
53
53
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
54
|
-
when the owner has not connected Google Workspace
|
|
54
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
55
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
56
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
55
57
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
56
58
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
57
59
|
|
|
58
60
|
## Choosing a Google account
|
|
59
61
|
|
|
60
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
62
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
61
63
|
|
|
62
64
|
```bash
|
|
63
65
|
bash execute.sh --account work@company.com ...
|
|
@@ -56,13 +56,15 @@ For designed decks (brand templates, images, video) use the Canva skills.
|
|
|
56
56
|
## Failures
|
|
57
57
|
|
|
58
58
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
59
|
-
when the owner has not connected Google Workspace
|
|
59
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
60
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
61
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
60
62
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
61
63
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
62
64
|
|
|
63
65
|
## Choosing a Google account
|
|
64
66
|
|
|
65
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
67
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
66
68
|
|
|
67
69
|
```bash
|
|
68
70
|
bash execute.sh --account work@company.com ...
|
|
@@ -44,13 +44,15 @@ bash execute.sh --id 1AbC…
|
|
|
44
44
|
## Failures
|
|
45
45
|
|
|
46
46
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
47
|
-
when the owner has not connected Google Workspace
|
|
47
|
+
when the owner has not connected Google Workspace. Run the `google-connect` skill
|
|
48
|
+
to post the owner a one-tap card in Slack (never send them to Crewly settings or
|
|
49
|
+
the Connections page — they are usually on a phone). Manual fallback: https://crewlyai.com/portal/integrations/google.
|
|
48
50
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
49
51
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
50
52
|
|
|
51
53
|
## Choosing a Google account
|
|
52
54
|
|
|
53
|
-
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever
|
|
55
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever the owner marked default). Name one explicitly when it matters:
|
|
54
56
|
|
|
55
57
|
```bash
|
|
56
58
|
bash execute.sh --account work@company.com ...
|
|
@@ -4717,12 +4717,21 @@ export declare const GOOGLE_WORKSPACE_CONSTANTS: {
|
|
|
4717
4717
|
* for want of a scope, or because the grant expired / was revoked.
|
|
4718
4718
|
*/
|
|
4719
4719
|
readonly REAUTH: {
|
|
4720
|
-
/**
|
|
4721
|
-
|
|
4722
|
-
|
|
4720
|
+
/**
|
|
4721
|
+
* A card that went out less than this long ago is not repeated for the
|
|
4722
|
+
* same product + Google account (concurrent failures share one card);
|
|
4723
|
+
* after it, a new failure posts a fresh card unless the owner has
|
|
4724
|
+
* reconnected (ms)
|
|
4725
|
+
*/
|
|
4726
|
+
readonly CARD_RESEND_AFTER_MS: number;
|
|
4727
|
+
/** First wait between looks at Cloud for the reconnect (ms) */
|
|
4723
4728
|
readonly POLL_INTERVAL_MS: 30000;
|
|
4724
|
-
/**
|
|
4725
|
-
readonly
|
|
4729
|
+
/** The wait grows by this factor after each look... */
|
|
4730
|
+
readonly POLL_BACKOFF_FACTOR: 1.5;
|
|
4731
|
+
/** ...up to this ceiling (ms) */
|
|
4732
|
+
readonly POLL_MAX_INTERVAL_MS: number;
|
|
4733
|
+
/** The card link never expires, so keep watching for the reconnect this long (ms) */
|
|
4734
|
+
readonly WATCH_MS: number;
|
|
4726
4735
|
/** Give up posting the card after this long, so the skill call is not held (ms) */
|
|
4727
4736
|
readonly POST_TIMEOUT_MS: 8000;
|
|
4728
4737
|
};
|
|
@@ -4738,6 +4747,12 @@ export declare const GOOGLE_WORKSPACE_CONSTANTS: {
|
|
|
4738
4747
|
readonly SLIDES_MAX_SLIDES: 60;
|
|
4739
4748
|
/** Dashboard path the Cloud consent flow returns to */
|
|
4740
4749
|
readonly SETTINGS_RETURN_PATH: "/connections?platform=google-workspace";
|
|
4750
|
+
/**
|
|
4751
|
+
* Cloud portal page that starts Google consent. It mints the consent
|
|
4752
|
+
* ticket when the owner opens it, so a link to it never expires and
|
|
4753
|
+
* carries no credential. Query: `products=<csv>&account=<email>&auto=1`.
|
|
4754
|
+
*/
|
|
4755
|
+
readonly PORTAL_CONNECT_PATH: "/portal/integrations/google";
|
|
4741
4756
|
/** Metadata headers requested on Gmail search hits */
|
|
4742
4757
|
readonly GMAIL_SEARCH_HEADERS: readonly ["From", "To", "Subject", "Date"];
|
|
4743
4758
|
/** RFC 2045 line width for base64 message bodies */
|
|
@@ -5664,7 +5679,7 @@ export declare const TICKET_CONSTANTS: {
|
|
|
5664
5679
|
readonly DONE_REACTION: "white_check_mark";
|
|
5665
5680
|
/**
|
|
5666
5681
|
* Receipts are off (owner, 2026-09-24): tickets are Crewly's own record
|
|
5667
|
-
* of the work — no 🎫 / ✅ /
|
|
5682
|
+
* of the work — no 🎫 / ✅ / "Recorded as TKT-…" in the owner's conversations.
|
|
5668
5683
|
*/
|
|
5669
5684
|
readonly ENABLED: false;
|
|
5670
5685
|
};
|
|
@@ -5741,7 +5756,7 @@ export declare const TICKET_CONSTANTS: {
|
|
|
5741
5756
|
/** 「打回 <reason>」 — send it back; group 2 is the reason */
|
|
5742
5757
|
readonly REJECT_PATTERN: RegExp;
|
|
5743
5758
|
/** Reason recorded when 打回 came without one */
|
|
5744
|
-
readonly REJECT_NO_REASON: "
|
|
5759
|
+
readonly REJECT_NO_REASON: "(no reason given)";
|
|
5745
5760
|
/** WorkItem title for a rework sent from the board */
|
|
5746
5761
|
readonly REWORK_TITLE: (tkt: string) => string;
|
|
5747
5762
|
};
|
|
@@ -6100,7 +6115,7 @@ export declare const ONBOARDING_CONSTANTS: {
|
|
|
6100
6115
|
/** Longest first task accepted */
|
|
6101
6116
|
readonly FIRST_TASK_MAX_LENGTH: 4000;
|
|
6102
6117
|
/** First line of the message the orchestrator receives for a first task */
|
|
6103
|
-
readonly FIRST_TASK_HEADER: "[
|
|
6118
|
+
readonly FIRST_TASK_HEADER: "[Initial setup · first task]";
|
|
6104
6119
|
/** Chat metadata `source` of a first task sent from setup */
|
|
6105
6120
|
readonly FIRST_TASK_SOURCE: "onboarding_first_task";
|
|
6106
6121
|
/** Query parameter that opens `/setup` at a step (e.g. `/setup?step=cloud`) */
|
|
@@ -6170,7 +6185,7 @@ export declare const BUNDLE_CONSTANTS: {
|
|
|
6170
6185
|
/** Chat metadata `source` of a first-week task */
|
|
6171
6186
|
readonly FIRST_WEEK_SOURCE: "bundle_first_week";
|
|
6172
6187
|
/** First line of a first-week task the orchestrator receives */
|
|
6173
|
-
readonly FIRST_WEEK_HEADER: "[
|
|
6188
|
+
readonly FIRST_WEEK_HEADER: "[Solution bundle · week one]";
|
|
6174
6189
|
/** How often the backend delivers due first-week tasks and resumes waiting deployments */
|
|
6175
6190
|
readonly TICK_INTERVAL_MS: number;
|
|
6176
6191
|
/** How often `crewly deploy-bundle` polls a running backend's job */
|