@crewx/wi 0.1.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/SKILL.md ADDED
@@ -0,0 +1,212 @@
1
+ ---
2
+ name: work-instruction
3
+ description: Work Instruction (WI) skill. Draft, review, and issue structured task assignments to agents.
4
+ metadata:
5
+ version: 0.1.0
6
+ ---
7
+
8
+ # Work Instruction Skill
9
+
10
+ > **Core principle**: Context belongs in the file, not in your head.
11
+ > An agent should be able to execute a WI without asking questions.
12
+
13
+ ## When to use
14
+
15
+ - When delegating work to an agent
16
+ - Before issuing a task to a worker agent
17
+ - When decomposing complex features into atomic units
18
+
19
+ **Never delegate to an agent without a Work Instruction.**
20
+
21
+ ---
22
+
23
+ ## Commands
24
+
25
+ ### draft — Create a draft
26
+
27
+ Takes the user's intent and drafts a Work Instruction.
28
+ The lead reads the design doc and fills in the details.
29
+
30
+ ```bash
31
+ npx skill work-instruction draft "task description"
32
+ ```
33
+
34
+ **Lead execution steps:**
35
+
36
+ 1. Check today's date + existing WI count → assign ID
37
+ ```bash
38
+ ls docs/wi/ | grep $(date +%Y%m%d) | wc -l
39
+ ```
40
+
41
+ 2. Read relevant section from design doc
42
+ ```bash
43
+ npx doc section docs/design.md "section name"
44
+ ```
45
+
46
+ 3. Identify affected files + **impact analysis**
47
+ ```bash
48
+ # Track symbol references
49
+ npx skill tsserver find "symbolName"
50
+ npx skill tsserver refs path/to/file.ts lineNumber
51
+
52
+ # If API changed, find consumers
53
+ npx search "endpointName" ./src/ui --glob="**/*.ts,**/*.tsx"
54
+
55
+ # If types changed, find usages
56
+ npx search "typeName" ./src --glob="**/*.ts,**/*.tsx"
57
+ ```
58
+
59
+ → Fill in `api_changed`, `schema_changed`, `consumers`, `risk_level`
60
+
61
+ 4. Validate atomicity (decide if decomposition needed)
62
+ - More than 3 files modified → decompose
63
+ - Estimated cost > $0.30 → decompose
64
+ - Backend + frontend together → separate (apply Contract-First)
65
+
66
+ 5. Create `docs/wi/WI-{YYYYMMDD}-{SEQ}.md`
67
+ - Template: `docs/wi/WI-TEMPLATE.md`
68
+
69
+ 6. **WI verification** — do not skip
70
+ - Imagine a world where all ACs pass. Run the scenario in your head without writing code.
71
+ - Picture a user using this feature for the first time:
72
+ - Input → Process → **Save** → **Read** → Use — is the full path connected?
73
+ - Any gaps like "it saves but there's no way to retrieve it"?
74
+ - Any dead ends in error cases?
75
+ - If gaps found → revise AC/scope, repeat from step 5
76
+ - Attach verification results when reporting the draft
77
+
78
+ 7. Report draft to user → await approval
79
+
80
+ ---
81
+
82
+ ### issue — Issue to an agent
83
+
84
+ Deliver an approved Work Instruction to the assigned agent.
85
+
86
+ ```bash
87
+ npx skill work-instruction issue WI-20260312-001
88
+ ```
89
+
90
+ **Issue steps:**
91
+
92
+ 1. Read WI file → check status (must be `approved`)
93
+
94
+ 2. Check WI's `impl_agent` (`consultant` is for advisory — not an issue target)
95
+
96
+ 3. Check agent memory (any in-progress work?)
97
+ ```bash
98
+ npx memory index {impl_agent}
99
+ ```
100
+
101
+ 4. Issue via `$CREWX_CLI x`:
102
+ ```bash
103
+ $CREWX_CLI x "@{impl_agent} Execute Work Instruction WI-{ID}.
104
+
105
+ Full WI:
106
+ {entire WI file content}
107
+
108
+ Report in the specified format when done." \
109
+ --thread="WI-{ID}" --result="WI-{ID}-impl"
110
+ ```
111
+
112
+ 5. Update WI status → `in-progress`
113
+
114
+ 6. Verify AC after completion report:
115
+ ```bash
116
+ npx tsc --noEmit
117
+ npx vitest run src/server/ # or src/ui/
118
+ ```
119
+
120
+ 7. If AC passes → status → `done`
121
+
122
+ ---
123
+
124
+ ### list — List WIs
125
+
126
+ ```bash
127
+ npx skill work-instruction list
128
+ npx skill work-instruction list --status=approved
129
+ npx skill work-instruction list --status=in-progress
130
+ ```
131
+
132
+ **Execution:**
133
+ ```bash
134
+ # Full list
135
+ ls docs/wi/ | grep "^WI-" | sort
136
+
137
+ # Filter by status
138
+ grep -l "status: approved" docs/wi/WI-*.md 2>/dev/null
139
+ ```
140
+
141
+ ---
142
+
143
+ ### review — Request lead review
144
+
145
+ Request a review from the `consultant` before issuing.
146
+
147
+ ```bash
148
+ npx skill work-instruction review WI-20260312-001
149
+ ```
150
+
151
+ ```bash
152
+ $CREWX_CLI q "@{consultant} Review this Work Instruction.
153
+ Check feasibility, missing items, and risks.
154
+
155
+ {entire WI file content}" \
156
+ --thread="WI-{ID}-review" --result="WI-{ID}-review"
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Contract-First Rule
162
+
163
+ When backend + frontend work is needed:
164
+
165
+ ```
166
+ ❌ Issue simultaneously (causes type drift)
167
+
168
+ ✅ Issue sequentially:
169
+ 1. WI-001: Backend TypeScript types/DTO definitions
170
+ 2. (after WI-001) WI-002: Backend service/controller implementation
171
+ 3. (after WI-002) WI-003: Frontend integration
172
+ ```
173
+
174
+ Enforce order with `depends_on`:
175
+ ```yaml
176
+ depends_on: ["WI-20260312-001"]
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Atomicity Criteria
182
+
183
+ | Condition | Decision |
184
+ |-----------|----------|
185
+ | 1-3 files modified | ✅ Ready to issue |
186
+ | 4+ files modified | ⚠️ Decompose |
187
+ | Estimated cost ≤ $0.30 | ✅ Ready to issue |
188
+ | Estimated cost > $0.30 | ⚠️ Decompose |
189
+ | Backend + frontend together | ⚠️ Separate + depends_on |
190
+ | Cannot verify with `tsc --noEmit` | ⚠️ Redefine AC |
191
+
192
+ ---
193
+
194
+ ## Failure Handling
195
+
196
+ When AC fails after agent completion report:
197
+
198
+ ```
199
+ 1st failure → Re-issue with error details (same thread)
200
+ 2nd failure → STOP, escalate to user
201
+ → Rollback WI status to draft, redesign
202
+ ```
203
+
204
+ **Two consecutive failures on the same error signals the WI itself needs rewriting.**
205
+
206
+ ---
207
+
208
+ ## References
209
+
210
+ - Template: [docs/wi/WI-TEMPLATE.md](../../docs/wi/WI-TEMPLATE.md)
211
+ - PM guide: [skills/pm/SKILL.md](../pm/SKILL.md)
212
+ - Decomposition strategy: [docs/research/multi-agent-divide-conquer.md](../../docs/research/multi-agent-divide-conquer.md)
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function main(inputArgs?: string[]): Promise<void>;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AAqDA,wBAAsB,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B9D"}
package/dist/cli.js ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.main = main;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ let PKG_VERSION = 'unknown';
41
+ try {
42
+ const _pkgPath = fs.existsSync(path.join(__dirname, 'package.json'))
43
+ ? path.join(__dirname, 'package.json')
44
+ : path.join(__dirname, '..', 'package.json');
45
+ const _pkg = JSON.parse(fs.readFileSync(_pkgPath, 'utf-8'));
46
+ if (_pkg?.version)
47
+ PKG_VERSION = String(_pkg.version);
48
+ }
49
+ catch { }
50
+ async function loadTracer() {
51
+ try {
52
+ return await Promise.resolve().then(() => __importStar(require('@crewx/shared/skill-tracer')));
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ function showDetailedUsage() {
59
+ const skillMd = path.join(__dirname, '..', 'SKILL.md');
60
+ if (fs.existsSync(skillMd)) {
61
+ process.stdout.write(fs.readFileSync(skillMd, 'utf-8'));
62
+ }
63
+ else {
64
+ console.log('No SKILL.md found. Use --help for usage.');
65
+ }
66
+ }
67
+ function printUsage() {
68
+ console.log(`
69
+ @crewx/wi@${PKG_VERSION} - Structured task delegation via Work Instructions
70
+
71
+ Usage:
72
+ wi <command> [args]
73
+
74
+ Commands:
75
+ wi usage Show detailed guide (SKILL.md)
76
+ wi draft <description> Draft a new Work Instruction (planned)
77
+ wi issue <WI-ID> Issue WI to assigned agent (planned)
78
+ wi list [--status=...] List Work Instructions (planned)
79
+ wi review <WI-ID> Request lead review (planned)
80
+
81
+ Options:
82
+ --version Show version
83
+ --help, -h Show this help
84
+
85
+ Note:
86
+ Phase 1 — only 'usage' is available. Other subcommands are planned.
87
+
88
+ Template: docs/wi/WI-TEMPLATE.md
89
+ For detailed usage guide: wi usage
90
+ `);
91
+ }
92
+ async function main(inputArgs) {
93
+ const args = inputArgs ?? process.argv.slice(2);
94
+ const command = args[0];
95
+ if (args.includes('--version')) {
96
+ console.log(PKG_VERSION);
97
+ return;
98
+ }
99
+ if (args.includes('--help') || args.includes('-h')) {
100
+ printUsage();
101
+ return;
102
+ }
103
+ if (command === 'usage') {
104
+ showDetailedUsage();
105
+ return;
106
+ }
107
+ if (command === 'draft' || command === 'issue' || command === 'list' || command === 'review') {
108
+ console.log(`\n '${command}' is not yet implemented (Phase 1).\n`);
109
+ console.log(` Run 'wi usage' for the full guide.\n`);
110
+ return;
111
+ }
112
+ printUsage();
113
+ }
114
+ if (require.main === module) {
115
+ loadTracer().then(tracer => {
116
+ const opts = tracer ? { skillVersion: tracer.getOwnSkillVersion(__dirname) } : {};
117
+ return tracer ? tracer.run('crewx/wi', () => main(), opts) : main();
118
+ }).catch((e) => {
119
+ console.error(e.message);
120
+ process.exit(1);
121
+ });
122
+ }
123
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@crewx/wi",
3
+ "version": "0.1.0",
4
+ "description": "Work Instruction engine for CrewX - structured task delegation",
5
+ "type": "commonjs",
6
+ "main": "dist/cli.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/cli.js",
10
+ "require": "./dist/cli.js",
11
+ "default": "./dist/cli.js"
12
+ },
13
+ "./cli": {
14
+ "import": "./dist/cli.js",
15
+ "require": "./dist/cli.js",
16
+ "default": "./dist/cli.js"
17
+ }
18
+ },
19
+ "bin": {
20
+ "wi": "./dist/cli.js"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "SKILL.md",
25
+ "templates/"
26
+ ],
27
+ "dependencies": {
28
+ "@crewx/shared": "0.0.5"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.0.0",
32
+ "typescript": "^5.0.0"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "clean": "rm -rf dist"
37
+ }
38
+ }
@@ -0,0 +1,153 @@
1
+ ---
2
+ wi_id: WI-{YYYYMMDD}-{SEQ}
3
+ title: ""
4
+ date: ""
5
+ author: ""
6
+ status: draft # draft | approved | in-progress | done | cancelled
7
+ priority: normal # critical | high | normal | low
8
+
9
+ # Assignment
10
+ assignee: "" # Agent assigned to this work
11
+ reviewer: "" # Agent to review
12
+
13
+ # Git
14
+ base_branch: main
15
+ target_branch: develop
16
+ worktree: false # true = work in isolated worktree
17
+
18
+ # Design doc cross-link
19
+ spec_id: "" # Design doc API ID (e.g. MSG.LIST)
20
+ design_doc: ""
21
+ design_section: ""
22
+ screens: [] # Affected screen IDs (e.g. THDUI002)
23
+
24
+ # Dependencies
25
+ depends_on: [] # WI IDs that must complete before this starts
26
+ blocks: [] # WI IDs blocked by this WI
27
+
28
+ # Impact
29
+ risk_level: low # low | medium | high | critical
30
+ api_changed: false # if true, contract_type + consumers required
31
+ contract_type: none # none | additive | breaking | deprecation
32
+ schema_changed: false # if true, check migration needs
33
+
34
+ # Consumers (required when api_changed: true)
35
+ consumers:
36
+ # - screen: THDUI002
37
+ # file: src/ui/pages/threads/ThreadDetailPage.tsx
38
+ # store: useThreadDetailStore
39
+ # component: MessageBubble
40
+
41
+ # Estimated scope (atomicity: ≤ $0.30, 1-3 files)
42
+ estimated_files: 0
43
+ estimated_cost: "$0.00"
44
+ ---
45
+
46
+ # {title}
47
+
48
+ ## Background (Why)
49
+
50
+ > Why this work is needed. 1-3 sentences.
51
+
52
+ ## Goal (What)
53
+
54
+ > What changes when this is complete. Feature perspective.
55
+
56
+ ## Scope
57
+
58
+ ### Files to modify
59
+
60
+ | File | Description |
61
+ |------|-------------|
62
+ | `path/to/file.ts` | description |
63
+
64
+ **Out of scope (do not touch)**
65
+
66
+ - list items
67
+
68
+ ## Impact Analysis
69
+
70
+ ### Design doc cross-link
71
+
72
+ > Summary of the relevant design doc section.
73
+
74
+ ```bash
75
+ npx doc section {design_doc} "{spec_id}"
76
+ ```
77
+
78
+ | Item | Value |
79
+ |------|-------|
80
+ | API ID | `{spec_id}` |
81
+ | Screen ID | `{screens}` |
82
+ | Section | `{design_section}` |
83
+
84
+ ### API / Type changes
85
+
86
+ > Skip this section if `api_changed: false`.
87
+
88
+ | Changed item | contract_type | Consumers (screen / file / store) |
89
+ |-------------|--------------|-----------------------------------|
90
+ | (none) | - | - |
91
+
92
+ ### Consumer impact checklist
93
+
94
+ > Required when `api_changed: true`. Empty = cannot approve.
95
+
96
+ - [ ] Affected screen IDs identified (`screens` field)
97
+ - [ ] Affected frontend components identified (`consumers.component`)
98
+ - [ ] Affected stores identified (`consumers.store`)
99
+ - [ ] If `contract_type: breaking`, issue separate consumer WI (add to `blocks`)
100
+ - [ ] DB schema change migration: (none / Phase N needed)
101
+
102
+ ### Side-effect risk areas
103
+
104
+ > Areas that broke in similar past work. "None" if none.
105
+
106
+ ### risk_level criteria
107
+
108
+ | Level | Condition |
109
+ |-------|-----------|
110
+ | `low` | Single file, no API change, existing tests sufficient |
111
+ | `medium` | 2-3 files, API change with ≤ 1 consumer |
112
+ | `high` | API change + 2+ consumers, or store refactoring |
113
+ | `critical` | DB schema change, or core SDK interface change |
114
+
115
+ > `high` or above: consult lead before implementation.
116
+
117
+ ---
118
+
119
+ ## Implementation Guide (How)
120
+
121
+ > Concrete instructions an agent can follow without judgment calls.
122
+ > Include code examples, type definitions, caveats.
123
+
124
+ ```typescript
125
+ // Example code (if applicable)
126
+ ```
127
+
128
+ ## Acceptance Criteria (AC)
129
+
130
+ > All must pass to mark "done". If any fails, STOP and report.
131
+
132
+ - [ ] `npx tsc --noEmit` passes
133
+ - [ ] `npx vitest run src/server/` passes (backend work)
134
+ - [ ] `npx vitest run src/ui/` passes (frontend work)
135
+ - [ ] (add feature-specific AC)
136
+
137
+ ## Completion Report Format
138
+
139
+ ```
140
+ ## Completion Report
141
+
142
+ ### Modified files
143
+ - path/to/file.ts (+N/-M)
144
+
145
+ ### tsc result
146
+ Pass / Fail
147
+
148
+ ### Test result
149
+ N tests passed
150
+
151
+ ### Remaining items
152
+ None / (list if any)
153
+ ```