@charzhu/openjaw-agent 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/LICENSE +21 -0
- package/README.md +546 -0
- package/config.yaml +72 -0
- package/dist/main.js +61348 -0
- package/dist/main.js.map +7 -0
- package/package.json +134 -0
- package/prompts/COMPUTER_USE.md +87 -0
- package/prompts/IDENTITY.md +33 -0
- package/prompts/REASONING.md +182 -0
- package/prompts/SAFETY.md +43 -0
- package/prompts/USER.md +37 -0
- package/skills/competitive-battlecard.md +98 -0
- package/skills/create-docx.md +174 -0
- package/skills/create-pdf-report.md +93 -0
- package/skills/create-pptx.md +109 -0
- package/skills/daily-briefing.md +65 -0
- package/skills/data-analysis.md +127 -0
- package/skills/deep-research.md +101 -0
- package/skills/desktop-cleanup.md +82 -0
- package/skills/doc-coauthoring.md +123 -0
- package/skills/email-drafting.md +141 -0
- package/skills/email-with-attachment.md +114 -0
- package/skills/internal-comms.md +88 -0
- package/skills/meeting-summarizer.md +72 -0
- package/skills/proofreading.md +77 -0
- package/skills/refresh-token.md +161 -0
- package/skills/skill-creator.md +122 -0
- package/skills/summarization.md +110 -0
- package/skills/translation.md +94 -0
- package/skills/web-research.md +93 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refresh-token
|
|
3
|
+
description: "Refreshes Microsoft Graph API tokens used by OpenJaw for Teams and Outlook."
|
|
4
|
+
whenToUse: "Graph API tokens are expired or need refreshing for Teams/Outlook automation"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Refresh Graph Token
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Refreshes Microsoft Graph API tokens (graph-chat + outlook-mail) used by OpenJaw for Teams and Outlook automation.
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
- Edge running with `--remote-debugging-port=9222 --remote-allow-origins=*`
|
|
14
|
+
- Logged into outlook.office.com in Edge
|
|
15
|
+
- Node.js 22+ with `ws` package (`npm i -g ws` if not installed)
|
|
16
|
+
|
|
17
|
+
## How to Execute
|
|
18
|
+
|
|
19
|
+
Write the following script to a temp file and run it. The script is fully self-contained.
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// Save this as a temp .mjs file and run with: node <tempfile>.mjs
|
|
23
|
+
import { WebSocket } from 'ws';
|
|
24
|
+
import { writeFileSync, readFileSync, mkdirSync, existsSync } from 'fs';
|
|
25
|
+
import { join } from 'path';
|
|
26
|
+
import { homedir } from 'os';
|
|
27
|
+
|
|
28
|
+
const CDP_PORT = 9222;
|
|
29
|
+
const CLIENT_ID = '9199bf20-a13f-4107-85dc-02114787ef48';
|
|
30
|
+
const TOKEN_DIR = join(homedir(), '.graph-token', 'tokens');
|
|
31
|
+
|
|
32
|
+
const AUDIENCES = [
|
|
33
|
+
{ name: 'graph-chat', audience: 'https://graph.microsoft.com' },
|
|
34
|
+
{ name: 'outlook-mail', audience: 'https://outlook.office.com' },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
function decodeJwt(jwt) {
|
|
38
|
+
try { return JSON.parse(Buffer.from(jwt.split('.')[1], 'base64url').toString()); }
|
|
39
|
+
catch { return null; }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function listPages() {
|
|
43
|
+
return await (await fetch(`http://localhost:${CDP_PORT}/json`)).json();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function evalInTab(wsUrl, expr) {
|
|
47
|
+
return new Promise(resolve => {
|
|
48
|
+
const ws = new WebSocket(wsUrl);
|
|
49
|
+
const timer = setTimeout(() => { ws.close(); resolve(null); }, 15000);
|
|
50
|
+
ws.on('open', () => ws.send(JSON.stringify({ id: 1, method: 'Runtime.evaluate', params: { expression: expr, returnByValue: true } })));
|
|
51
|
+
ws.on('message', d => { const r = JSON.parse(d.toString()); if (r.id === 1) { clearTimeout(timer); ws.close(); resolve(r.result?.result?.value ?? null); } });
|
|
52
|
+
ws.on('error', () => { clearTimeout(timer); resolve(null); });
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function openTab(url) {
|
|
57
|
+
const ver = await (await fetch(`http://localhost:${CDP_PORT}/json/version`)).json();
|
|
58
|
+
return new Promise(resolve => {
|
|
59
|
+
const ws = new WebSocket(ver.webSocketDebuggerUrl);
|
|
60
|
+
const timer = setTimeout(() => { ws.close(); resolve(null); }, 15000);
|
|
61
|
+
ws.on('open', () => ws.send(JSON.stringify({ id: 1, method: 'Target.createTarget', params: { url } })));
|
|
62
|
+
ws.on('message', d => { const r = JSON.parse(d.toString()); if (r.id === 1) { clearTimeout(timer); ws.close(); resolve(r.result?.targetId); } });
|
|
63
|
+
ws.on('error', () => { clearTimeout(timer); resolve(null); });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const EXTRACT_RT = `(function(){
|
|
68
|
+
var rtKeys=Object.keys(localStorage).filter(k=>k.includes('refreshtoken'));
|
|
69
|
+
if(!rtKeys.length) return JSON.stringify({error:'no_rt'});
|
|
70
|
+
var rtKey=rtKeys.find(k=>k.includes('|refreshtoken|${CLIENT_ID}|'))||rtKeys[0];
|
|
71
|
+
var rt=JSON.parse(localStorage.getItem(rtKey));
|
|
72
|
+
var acctKeys=JSON.parse(localStorage.getItem('msal.2.account.keys')||'[]');
|
|
73
|
+
if(!acctKeys.length) return JSON.stringify({error:'no_account'});
|
|
74
|
+
var acct=JSON.parse(localStorage.getItem(acctKeys[0]));
|
|
75
|
+
var tid=acct.realm||acct.tenantId||acct.homeAccountId?.split('.')[1]||'';
|
|
76
|
+
return JSON.stringify({refreshToken:rt.data||rt.secret||'',tenantId:tid});
|
|
77
|
+
})()`;
|
|
78
|
+
|
|
79
|
+
async function main() {
|
|
80
|
+
// Check CDP
|
|
81
|
+
try { await fetch(`http://localhost:${CDP_PORT}/json/version`); }
|
|
82
|
+
catch { console.error('❌ CDP not available. Start Edge with --remote-debugging-port=9222'); process.exit(1); }
|
|
83
|
+
|
|
84
|
+
// Find Outlook tab
|
|
85
|
+
let pages = await listPages();
|
|
86
|
+
let tab = pages.find(p => (p.url?.includes('outlook.office.com') || p.url?.includes('outlook.cloud.microsoft')) && p.webSocketDebuggerUrl && p.type === 'page');
|
|
87
|
+
|
|
88
|
+
if (!tab) {
|
|
89
|
+
console.log('⏳ Opening Outlook...');
|
|
90
|
+
await openTab('https://outlook.office.com/mail/');
|
|
91
|
+
for (let i = 0; i < 20; i++) {
|
|
92
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
93
|
+
pages = await listPages();
|
|
94
|
+
tab = pages.find(p => p.url?.includes('outlook.office') && p.webSocketDebuggerUrl && p.type === 'page');
|
|
95
|
+
if (tab) break;
|
|
96
|
+
}
|
|
97
|
+
if (!tab) { console.error('❌ Outlook did not load'); process.exit(1); }
|
|
98
|
+
await new Promise(r => setTimeout(r, 8000)); // Wait for MSAL
|
|
99
|
+
pages = await listPages();
|
|
100
|
+
tab = pages.find(p => p.url?.includes('outlook.office') && p.webSocketDebuggerUrl && p.type === 'page');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log('✅ Outlook tab found');
|
|
104
|
+
|
|
105
|
+
// Extract RT
|
|
106
|
+
const raw = await evalInTab(tab.webSocketDebuggerUrl, EXTRACT_RT);
|
|
107
|
+
if (!raw) { console.error('❌ CDP eval failed'); process.exit(1); }
|
|
108
|
+
const info = JSON.parse(raw);
|
|
109
|
+
if (info.error) { console.error('❌ ' + info.error); process.exit(1); }
|
|
110
|
+
console.log('✅ RT extracted (tenant: ' + info.tenantId.slice(0, 8) + '...)');
|
|
111
|
+
|
|
112
|
+
// Exchange for access tokens
|
|
113
|
+
mkdirSync(TOKEN_DIR, { recursive: true });
|
|
114
|
+
for (const { name, audience } of AUDIENCES) {
|
|
115
|
+
const body = new URLSearchParams({ client_id: CLIENT_ID, grant_type: 'refresh_token', refresh_token: info.refreshToken, scope: audience + '/.default offline_access' });
|
|
116
|
+
const resp = await fetch(`https://login.microsoftonline.com/${info.tenantId}/oauth2/v2.0/token`, {
|
|
117
|
+
method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Origin: 'https://outlook.office.com' }, body: body.toString()
|
|
118
|
+
});
|
|
119
|
+
const result = await resp.json();
|
|
120
|
+
if (result.access_token) {
|
|
121
|
+
const exp = decodeJwt(result.access_token)?.exp || 0;
|
|
122
|
+
const mins = Math.floor((exp - Date.now() / 1000) / 60);
|
|
123
|
+
writeFileSync(join(TOKEN_DIR, name + '.json'), JSON.stringify({ access_token: result.access_token, token_type: 'Bearer', saved_at: new Date().toISOString(), source: 'refresh-skill' }, null, 2));
|
|
124
|
+
console.log('✅ ' + name + ': refreshed (' + mins + 'm validity)');
|
|
125
|
+
} else {
|
|
126
|
+
console.error('❌ ' + name + ': ' + (result.error_description || result.error || 'unknown'));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
main().catch(e => { console.error('❌ ' + e.message); process.exit(1); });
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## How to Run
|
|
135
|
+
|
|
136
|
+
The agent should:
|
|
137
|
+
1. Write the above script to a temp file: `file_write({ path: "<temp>/refresh-graph.mjs", content: <script> })`
|
|
138
|
+
2. Execute: `system_run({ command: "node <temp>/refresh-graph.mjs", timeout: 60000 })`
|
|
139
|
+
3. Verify: `outlook_switch_channel("graph")` → `outlook_go_to_inbox()`
|
|
140
|
+
|
|
141
|
+
## Token File Locations
|
|
142
|
+
```
|
|
143
|
+
~/.graph-token/tokens/graph-chat.json — Teams Graph channel
|
|
144
|
+
~/.graph-token/tokens/outlook-mail.json — Outlook Graph channel
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Troubleshooting
|
|
148
|
+
|
|
149
|
+
| Problem | Fix |
|
|
150
|
+
|---------|-----|
|
|
151
|
+
| CDP not available | Restart Edge with `--remote-debugging-port=9222 --remote-allow-origins=*` |
|
|
152
|
+
| `no_rt` error | Outlook Web session expired — log in manually |
|
|
153
|
+
| RT exchange failed | Refresh token revoked — close Edge, reopen, log in fresh |
|
|
154
|
+
| Tokens expire in ~80 min | Run this skill periodically |
|
|
155
|
+
|
|
156
|
+
## Verification
|
|
157
|
+
After refresh, test with:
|
|
158
|
+
```
|
|
159
|
+
outlook_switch_channel("graph") → outlook_go_to_inbox()
|
|
160
|
+
teams_switch_channel("graph") → teams_read_messages()
|
|
161
|
+
```
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-creator
|
|
3
|
+
description: "Create new skills, modify existing skills, and improve skill quality."
|
|
4
|
+
whenToUse: "Jon identifies a new capability gap that should be systematized"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Skill Creator (Meta-Skill)
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Create new skills for Jon, modify existing skills, and improve skill quality. This is the meta-skill — the skill that makes other skills. Based on Anthropic's skill-creator but adapted for OpenJaw Agent.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
- Jon identifies a new capability gap that should be systematized
|
|
14
|
+
- User asks to "teach Jon something new" or "add a new skill"
|
|
15
|
+
- After completing a novel task that should be repeatable
|
|
16
|
+
- When an existing skill needs improvement based on real usage
|
|
17
|
+
|
|
18
|
+
## Skill Creation Process
|
|
19
|
+
|
|
20
|
+
### 1. Capture Intent
|
|
21
|
+
Understand what the skill should do:
|
|
22
|
+
- What task does this skill enable?
|
|
23
|
+
- When should it trigger? (what user phrases/contexts)
|
|
24
|
+
- What's the expected output?
|
|
25
|
+
- What tools/APIs does it need?
|
|
26
|
+
- What are the common failure modes?
|
|
27
|
+
|
|
28
|
+
### 2. Research & Reference
|
|
29
|
+
Before writing, gather context:
|
|
30
|
+
- Check existing skills for overlap: `file_list("~/.openjaw-agent/skills")` and `file_list("<package>/skills")`
|
|
31
|
+
- Search GitHub for similar skills: `web_search("SKILL.md [topic] agent")`
|
|
32
|
+
- Check Anthropic's official skills: `web_fetch("https://raw.githubusercontent.com/anthropics/skills/main/skills/[name]/SKILL.md")`
|
|
33
|
+
- Review memory for past experiences: `memory_search("[topic]")`
|
|
34
|
+
|
|
35
|
+
### 3. Write the SKILL.md
|
|
36
|
+
|
|
37
|
+
#### Required Structure
|
|
38
|
+
```markdown
|
|
39
|
+
# Skill: [Name]
|
|
40
|
+
|
|
41
|
+
## Description
|
|
42
|
+
[1-2 sentences: What it does. Be "pushy" — list all trigger phrases and contexts
|
|
43
|
+
so the skill doesn't under-trigger.]
|
|
44
|
+
|
|
45
|
+
## When to Use
|
|
46
|
+
- [Trigger condition 1]
|
|
47
|
+
- [Trigger condition 2]
|
|
48
|
+
- [Chinese trigger phrase]
|
|
49
|
+
- [English trigger phrase]
|
|
50
|
+
|
|
51
|
+
## Prerequisites
|
|
52
|
+
- [Required tools, libraries, APIs]
|
|
53
|
+
|
|
54
|
+
## Workflow / Steps
|
|
55
|
+
[The core instructions — step by step]
|
|
56
|
+
|
|
57
|
+
## Important Notes
|
|
58
|
+
[Gotchas, edge cases, lessons learned from real usage]
|
|
59
|
+
|
|
60
|
+
## Output & Delivery
|
|
61
|
+
[How to deliver the result to the user]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Writing Guidelines
|
|
65
|
+
- **Be specific, not generic** — include actual code snippets, file paths, API endpoints
|
|
66
|
+
- **Include failure modes** — what goes wrong and how to fix it
|
|
67
|
+
- **Use real examples** from actual usage with CharZ
|
|
68
|
+
- **Include Chinese trigger phrases** — CharZ communicates in both languages
|
|
69
|
+
- **Reference other skills** — skills should compose together (e.g., "use email-with-attachment skill to send")
|
|
70
|
+
- **Keep it actionable** — every section should help complete the task
|
|
71
|
+
- **"Pushy" descriptions** — list many trigger conditions to prevent under-triggering
|
|
72
|
+
|
|
73
|
+
#### Anti-Patterns to Avoid
|
|
74
|
+
- ❌ Generic advice without specific implementation
|
|
75
|
+
- ❌ Listing tools without showing how to use them
|
|
76
|
+
- ❌ Ignoring the actual environment (Windows, Chinese fonts, Outlook REST API)
|
|
77
|
+
- ❌ Not referencing other skills that should compose together
|
|
78
|
+
- ❌ Missing error handling / troubleshooting section
|
|
79
|
+
|
|
80
|
+
### 4. Save & Register
|
|
81
|
+
```python
|
|
82
|
+
# Save to user skills directory (NOT the bundled skills dir)
|
|
83
|
+
file_write("~/.openjaw-agent/skills/{skill-name}.md", content)
|
|
84
|
+
|
|
85
|
+
# Update memory
|
|
86
|
+
memory_append("Added new skill: {name} — {description}")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 5. Test
|
|
90
|
+
After creating a skill, ideally test it:
|
|
91
|
+
- Try triggering it with a realistic user request
|
|
92
|
+
- Verify the steps actually work in the current environment
|
|
93
|
+
- Check that referenced tools/APIs are available
|
|
94
|
+
|
|
95
|
+
### 6. Iterate
|
|
96
|
+
Skills should improve based on real usage:
|
|
97
|
+
- When a skill fails or produces suboptimal results → update it
|
|
98
|
+
- When new tools become available → enhance the skill
|
|
99
|
+
- When user gives feedback → incorporate it
|
|
100
|
+
- Periodically review skills for staleness
|
|
101
|
+
|
|
102
|
+
## Skill Quality Checklist
|
|
103
|
+
- [ ] Has clear trigger conditions (English + Chinese)
|
|
104
|
+
- [ ] Has specific, actionable steps (not just advice)
|
|
105
|
+
- [ ] Includes code snippets with real paths/APIs
|
|
106
|
+
- [ ] References other composable skills
|
|
107
|
+
- [ ] Has troubleshooting / error handling section
|
|
108
|
+
- [ ] Has been tested at least once
|
|
109
|
+
- [ ] Includes lessons from real usage
|
|
110
|
+
|
|
111
|
+
## Current Skills Directory
|
|
112
|
+
Path: `~/.openjaw-agent/skills/` (user skills — agent-created, persists across updates)
|
|
113
|
+
|
|
114
|
+
Skills compose together — for example:
|
|
115
|
+
- doc-coauthoring → create-pdf-report → email-with-attachment
|
|
116
|
+
- deep-research → summarization → internal-comms → email-drafting
|
|
117
|
+
- meeting-summarizer → translation → proofreading
|
|
118
|
+
|
|
119
|
+
## Skill Naming Convention
|
|
120
|
+
- Lowercase with hyphens: `skill-name.md`
|
|
121
|
+
- Descriptive but concise: `create-pdf-report.md`, not `pdf.md`
|
|
122
|
+
- Action-oriented when possible: `email-drafting.md`, not `emails.md`
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summarization
|
|
3
|
+
description: "Summarize long content into concise, structured summaries."
|
|
4
|
+
whenToUse: "User pastes long text and asks for a summary"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Summarization
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Summarize long content (emails, documents, chat threads, articles) into concise, structured summaries. Supports extractive (key sentences), abstractive (rewritten), and hierarchical (multi-level) approaches.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
- User pastes long text and asks for a summary
|
|
14
|
+
- User asks to summarize emails, Teams chats, or documents
|
|
15
|
+
- User says "太长了帮我总结" or "TL;DR" or "summarize this"
|
|
16
|
+
- After reading a long email thread or chat history
|
|
17
|
+
|
|
18
|
+
## Approach Selection
|
|
19
|
+
|
|
20
|
+
| Content Type | Best Approach | Output Length |
|
|
21
|
+
|-------------|--------------|---------------|
|
|
22
|
+
| Single email | Extractive (key points) | 2-3 bullets |
|
|
23
|
+
| Email thread (5+ msgs) | Abstractive + timeline | 5-10 bullets |
|
|
24
|
+
| Meeting transcript | Hierarchical (decisions > discussion > details) | ~1 page |
|
|
25
|
+
| Technical document | Abstractive + key terms | Paragraph + bullet points |
|
|
26
|
+
| Chat thread (50+ msgs) | Thematic grouping | Grouped bullets by topic |
|
|
27
|
+
| News article | Extractive headline + key points | 3-5 bullets |
|
|
28
|
+
|
|
29
|
+
## Workflow
|
|
30
|
+
|
|
31
|
+
### 1. Assess the Content
|
|
32
|
+
- Length: How long is the source?
|
|
33
|
+
- Type: Email? Chat? Document? Article?
|
|
34
|
+
- Purpose: Why does the user want a summary? (Decision? Catch up? Share?)
|
|
35
|
+
|
|
36
|
+
### 2. Apply the Right Technique
|
|
37
|
+
|
|
38
|
+
#### Extractive (Pull key sentences)
|
|
39
|
+
Best for: Short-medium content where exact wording matters
|
|
40
|
+
```
|
|
41
|
+
- Identify the most important 3-5 sentences
|
|
42
|
+
- Preserve original phrasing
|
|
43
|
+
- Bold key terms
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Abstractive (Rewrite concisely)
|
|
47
|
+
Best for: Long content that needs simplification
|
|
48
|
+
```
|
|
49
|
+
- Understand the overall message
|
|
50
|
+
- Rewrite in fewer words without losing meaning
|
|
51
|
+
- Use simpler language
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Hierarchical (Multi-level)
|
|
55
|
+
Best for: Complex content with multiple topics
|
|
56
|
+
```
|
|
57
|
+
Level 1: One-line summary (< 20 words)
|
|
58
|
+
Level 2: Key points (3-5 bullets)
|
|
59
|
+
Level 3: Detailed summary (paragraph per topic)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Thematic (Group by topic)
|
|
63
|
+
Best for: Long chat threads with multiple interleaved discussions
|
|
64
|
+
```
|
|
65
|
+
Group messages by topic:
|
|
66
|
+
- Topic A: [Summary of all messages about topic A]
|
|
67
|
+
- Topic B: [Summary of all messages about topic B]
|
|
68
|
+
- Action items: [Extracted from all topics]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Format Output
|
|
72
|
+
|
|
73
|
+
#### Quick Summary (default)
|
|
74
|
+
```
|
|
75
|
+
**TL;DR:** [One sentence summary]
|
|
76
|
+
|
|
77
|
+
Key points:
|
|
78
|
+
• [Point 1]
|
|
79
|
+
• [Point 2]
|
|
80
|
+
• [Point 3]
|
|
81
|
+
|
|
82
|
+
Action needed: [If any]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Detailed Summary
|
|
86
|
+
```
|
|
87
|
+
## Summary: [Title/Subject]
|
|
88
|
+
|
|
89
|
+
**Context:** [Why this matters]
|
|
90
|
+
|
|
91
|
+
### Main Points
|
|
92
|
+
1. [Point with detail]
|
|
93
|
+
2. [Point with detail]
|
|
94
|
+
|
|
95
|
+
### Decisions Made
|
|
96
|
+
- [Decision 1]
|
|
97
|
+
|
|
98
|
+
### Action Items
|
|
99
|
+
- [Owner]: [Action] by [Date]
|
|
100
|
+
|
|
101
|
+
### What's Still Open
|
|
102
|
+
- [Unresolved question]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 4. Rules
|
|
106
|
+
- **Match the language** of the source content
|
|
107
|
+
- **Never add information** not in the source
|
|
108
|
+
- **Preserve nuance** — don't oversimplify disagreements
|
|
109
|
+
- **Front-load the most important info** — if user only reads first 2 lines, they get the gist
|
|
110
|
+
- **For sensitive content** — follow the confidentiality rules (no salary/review info)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: translation
|
|
3
|
+
description: "Translate text between Chinese and English with cultural adaptation and natural tone."
|
|
4
|
+
whenToUse: "User asks to translate text between Chinese and English"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Translation (Chinese-English)
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Translate text between Chinese and English with cultural adaptation, natural tone, and technical term consistency. Optimized for Microsoft PM work context.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
- User asks to translate text between Chinese and English
|
|
14
|
+
- User says "翻译一下" or "translate this"
|
|
15
|
+
- User needs to convert Chinese notes to English email or vice versa
|
|
16
|
+
- User needs help polishing English/Chinese writing
|
|
17
|
+
|
|
18
|
+
## Translation Principles
|
|
19
|
+
|
|
20
|
+
### 1. Meaning Over Literal
|
|
21
|
+
- Don't translate word-by-word — translate the meaning
|
|
22
|
+
- Chinese idioms → English equivalents (not literal)
|
|
23
|
+
- English jargon → Natural Chinese (not transliteration)
|
|
24
|
+
|
|
25
|
+
### 2. Tone Matching
|
|
26
|
+
| Source Tone | Translation Approach |
|
|
27
|
+
|------------|---------------------|
|
|
28
|
+
| Formal business email | Maintain formality level |
|
|
29
|
+
| Casual team chat | Keep it casual and natural |
|
|
30
|
+
| Technical document | Precise terminology, clear structure |
|
|
31
|
+
| Leadership update | Confident, data-driven, concise |
|
|
32
|
+
|
|
33
|
+
### 3. Technical Term Consistency
|
|
34
|
+
Keep these in English (don't translate):
|
|
35
|
+
- Product names: Copilot, BizChat, Teams, Outlook
|
|
36
|
+
- Technical terms: token, cache, latency, API, LLM, prompt
|
|
37
|
+
- Metrics: CIE, DAU, MAU, P95, SLA
|
|
38
|
+
- Methodologies: Agile, Scrum, sprint, standup
|
|
39
|
+
|
|
40
|
+
### 4. Chinese → English
|
|
41
|
+
```
|
|
42
|
+
Approach:
|
|
43
|
+
1. Understand the full meaning in Chinese
|
|
44
|
+
2. Restructure for English grammar (SVO, shorter sentences)
|
|
45
|
+
3. Make it sound native — not "translated from Chinese"
|
|
46
|
+
4. Keep technical terms in English
|
|
47
|
+
5. Adjust formality for Western business culture
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Common patterns:
|
|
51
|
+
- 关于...的问题 → "Regarding..." or just state the issue directly
|
|
52
|
+
- 请问一下 → Remove (just ask the question directly)
|
|
53
|
+
- 辛苦了 → "Thanks for your help" / "Appreciate the effort"
|
|
54
|
+
- 麻烦你了 → "Would you mind..." / "Could you please..."
|
|
55
|
+
|
|
56
|
+
### 5. English → Chinese
|
|
57
|
+
```
|
|
58
|
+
Approach:
|
|
59
|
+
1. Understand the full meaning in English
|
|
60
|
+
2. Restructure for Chinese flow (topic-comment, longer compound sentences OK)
|
|
61
|
+
3. Make it sound natural Chinese — not "翻译腔"
|
|
62
|
+
4. Keep technical terms in English (don't force-translate)
|
|
63
|
+
5. Adjust for Chinese business culture (more polite hedging)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Common patterns:
|
|
67
|
+
- "I'd like to..." → 我想...
|
|
68
|
+
- "Could you..." → 麻烦你.../能不能帮忙...
|
|
69
|
+
- "FYI" → 供参考
|
|
70
|
+
- "Heads up" → 提前知会一下
|
|
71
|
+
- "Action needed" → 需要你的action
|
|
72
|
+
|
|
73
|
+
### 6. Quality Checks
|
|
74
|
+
- Read the translation out loud — does it sound natural?
|
|
75
|
+
- Would a native speaker write it this way?
|
|
76
|
+
- Are all technical terms consistent?
|
|
77
|
+
- Is the tone appropriate for the audience?
|
|
78
|
+
- No "翻译腔" (translationese)
|
|
79
|
+
|
|
80
|
+
## Example
|
|
81
|
+
|
|
82
|
+
### Chinese → English
|
|
83
|
+
```
|
|
84
|
+
Chinese: 这个feature的latency有点高,P95到了2秒,我们需要跟engine team对齐一下优化方案,争取下个sprint能降到1.5秒以下。
|
|
85
|
+
|
|
86
|
+
English: The latency for this feature is higher than expected — P95 is at 2 seconds. We need to sync with the engine team on an optimization plan, targeting sub-1.5s by next sprint.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### English → Chinese
|
|
90
|
+
```
|
|
91
|
+
English: We're seeing a regression in cache hit rate after the last deployment. The impact is ~5% increase in token consumption. I've filed a bug and the team is investigating.
|
|
92
|
+
|
|
93
|
+
Chinese: 上次部署后cache hit rate出现了回退,token消耗大概增加了5%。Bug已经提了,团队在排查中。
|
|
94
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-research
|
|
3
|
+
description: "Conduct structured web research on topics, competitors, or technologies."
|
|
4
|
+
whenToUse: "User asks to research a topic, product, or competitor"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: Web Research & Competitor Analysis
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Conduct structured web research on topics, competitors, or technologies. Compile findings into organized reports. Useful for PM work like compete analysis, market research, and technology scouting.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
- User asks to research a topic, product, or competitor
|
|
14
|
+
- User asks to compare products or technologies
|
|
15
|
+
- User asks "帮我调研一下" or "看看竞品怎么做的"
|
|
16
|
+
- Need to gather external information for decision-making
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Define Research Scope
|
|
21
|
+
Before searching, clarify:
|
|
22
|
+
- What specific questions need answers?
|
|
23
|
+
- What competitors/products to cover?
|
|
24
|
+
- What time frame is relevant?
|
|
25
|
+
- What format for the output?
|
|
26
|
+
|
|
27
|
+
### 2. Multi-Source Research
|
|
28
|
+
```
|
|
29
|
+
# Search with multiple angles
|
|
30
|
+
web_search("topic + specific question 1")
|
|
31
|
+
web_search("topic + competitor name")
|
|
32
|
+
web_search("topic + latest news 2026")
|
|
33
|
+
web_search("topic + comparison OR vs OR alternative")
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Deep Dive on Key Sources
|
|
37
|
+
```
|
|
38
|
+
# Fetch full content from promising results
|
|
39
|
+
web_fetch(url, max_length=8000)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 4. Structured Output Template
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
## [Topic] Research Report — [Date]
|
|
46
|
+
|
|
47
|
+
### Executive Summary
|
|
48
|
+
[2-3 sentence overview of key findings]
|
|
49
|
+
|
|
50
|
+
### Key Findings
|
|
51
|
+
|
|
52
|
+
#### 1. [Finding Area 1]
|
|
53
|
+
- **What**: Description
|
|
54
|
+
- **So what**: Why this matters
|
|
55
|
+
- **Source**: [URL]
|
|
56
|
+
|
|
57
|
+
#### 2. [Finding Area 2]
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
### Competitor Comparison
|
|
61
|
+
| Feature | Product A | Product B | Our Product |
|
|
62
|
+
|---------|-----------|-----------|-------------|
|
|
63
|
+
| Feature 1 | ✅ | ❌ | ✅ |
|
|
64
|
+
| Feature 2 | ❌ | ✅ | 🟡 |
|
|
65
|
+
|
|
66
|
+
### Implications for Us
|
|
67
|
+
1. [Actionable insight 1]
|
|
68
|
+
2. [Actionable insight 2]
|
|
69
|
+
|
|
70
|
+
### Sources
|
|
71
|
+
1. [Title](URL) — accessed [date]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 5. Quality Checks
|
|
75
|
+
- Cross-reference claims across multiple sources
|
|
76
|
+
- Check source dates — prefer recent information
|
|
77
|
+
- Distinguish facts from opinions
|
|
78
|
+
- Note any gaps in available information
|
|
79
|
+
|
|
80
|
+
## Compete Analysis Framework (for PM work)
|
|
81
|
+
1. **Product capabilities**: Feature comparison matrix
|
|
82
|
+
2. **User experience**: UX/UI differences
|
|
83
|
+
3. **Performance**: Speed, accuracy, reliability
|
|
84
|
+
4. **Pricing**: Cost comparison
|
|
85
|
+
5. **Market position**: User base, growth trends
|
|
86
|
+
6. **Strengths to learn from**: What they do better
|
|
87
|
+
7. **Weaknesses to exploit**: Where we can win
|
|
88
|
+
|
|
89
|
+
## Important Notes
|
|
90
|
+
- Always cite sources with URLs
|
|
91
|
+
- Clearly mark speculation vs confirmed facts
|
|
92
|
+
- For sensitive compete data, check if it's public before sharing
|
|
93
|
+
- Save research output as PDF for easy sharing (use create-pdf-report skill)
|