@crewx/wi 0.1.10-rc.19 → 0.1.10-rc.190

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 CHANGED
@@ -11,6 +11,23 @@ metadata:
11
11
  > **Core principle**: Context belongs in the file, not in your head.
12
12
  > An agent should be able to execute a WI without asking questions.
13
13
 
14
+ ## Command support
15
+
16
+ The dispatch logic in `packages/built-in/wi/cli.ts` is the source of truth for this table.
17
+
18
+ | Route | Status | Notes |
19
+ |--------|--------|-------|
20
+ | `usage` | Implemented | Shows this guide. |
21
+ | `create-batch` | Implemented | Creates gated draft WIs from batch JSON. |
22
+ | `board tick` | Implemented | Advances one approved board WI when gates pass. |
23
+ | `board digest` | Implemented | Sends and prints the overnight board summary. |
24
+ | `draft` | Planned / not implemented | Manual procedure below; not a runnable CLI route. |
25
+ | `issue` | Planned / not implemented | Manual procedure below; not a runnable CLI route. |
26
+ | `list` | Planned / not implemented | Manual procedure below; not a runnable CLI route. |
27
+ | `review` | Planned / not implemented | Manual procedure below; not a runnable CLI route. |
28
+
29
+ The four planned routes currently print `'<command>' is not yet implemented.` and return exit code `0`. Do not treat that exit code as proof that the requested operation succeeded.
30
+
14
31
  ## When to use
15
32
 
16
33
  - When delegating work to an agent
@@ -21,17 +38,80 @@ metadata:
21
38
 
22
39
  ---
23
40
 
24
- ## Commands
41
+ ## Implemented commands
25
42
 
26
- ### draft — Create a draft
43
+ ### create-batch — Materialize a gated WI plan
27
44
 
28
- Takes the user's intent and drafts a Work Instruction.
29
- The lead reads the design doc and fills in the details.
45
+ Creates multiple draft WIs in one atomic batch. Use this after a plan approval gate, not while brainstorming.
46
+
47
+ Input is JSON from `--file` or stdin:
48
+
49
+ ```json
50
+ {
51
+ "board": "brd_release",
52
+ "source": "manual",
53
+ "items": [
54
+ {
55
+ "title": "Implement SDK contract",
56
+ "assignee": "core_dev",
57
+ "depends_on": [],
58
+ "body": "Full WI body markdown"
59
+ }
60
+ ]
61
+ }
62
+ ```
63
+
64
+ ```bash
65
+ crewx wi create-batch --file .crewx/plan.json
66
+ cat .crewx/plan.json | crewx wi create-batch
67
+ ```
68
+
69
+ Output:
70
+
71
+ ```json
72
+ { "created": [{ "wi_id": "WI-20260730-001", "title": "Implement SDK contract" }] }
73
+ ```
74
+
75
+ All created WIs start as `draft` and include `board`, `source` (default `manual`), and `depends_on` frontmatter. ID allocation is locked across processes.
76
+
77
+ ### board tick / digest — Goal-board automatic chain
78
+
79
+ `tick` advances at most one WI from a board batch, after conservative gates:
80
+
81
+ ```bash
82
+ crewx wi board tick brd_release --json
83
+ ```
84
+
85
+ Cron registration must use command mode and a literal board id. Do not interpolate a
86
+ board name, WI title, or other free text into the scheduled command string.
87
+
88
+ ```bash
89
+ crewx cron add "0 * * * *" "crewx wi board tick brd_release --json" --mode command --name "Goal board tick"
90
+ ```
91
+
92
+ Tick behavior:
93
+
94
+ - Uses `.crewx/boards/<brd-id>/state.json` under a board file lock.
95
+ - Checks subscription usage limits through the CrewX server; if unavailable, skips the tick and increments `skippedTicks`.
96
+ - Runs only one workflow at a time.
97
+ - Never auto-approves `approval` nodes. Human-gated runs are marked `human_wait`.
98
+ - Stops the chain after three consecutive failures and sends a notification.
99
+
100
+ `digest` sends the overnight summary notification and includes `metadata.boardId`:
30
101
 
31
102
  ```bash
32
- npx crewx skill wi draft "task description"
103
+ crewx wi board digest brd_release --json
33
104
  ```
34
105
 
106
+ ## Manual procedures
107
+
108
+ ### Manual procedure: draft — Create a draft
109
+
110
+ There is no implemented CLI route for `draft`; follow this procedure manually.
111
+
112
+ Takes the user's intent and drafts a Work Instruction.
113
+ The lead reads the design doc and fills in the details.
114
+
35
115
  **Lead execution steps:**
36
116
 
37
117
  1. Check today's date + existing WI count → assign ID
@@ -41,20 +121,20 @@ npx crewx skill wi draft "task description"
41
121
 
42
122
  2. Read relevant section from design doc
43
123
  ```bash
44
- npx doc section docs/design.md "section name"
124
+ crewx doc section docs/design.md "section name"
45
125
  ```
46
126
 
47
127
  3. Identify affected files + **impact analysis**
48
128
  ```bash
49
129
  # Track symbol references
50
- npx skill tsserver find "symbolName"
51
- npx skill tsserver refs path/to/file.ts lineNumber
130
+ crewx skill tsserver find "symbolName"
131
+ crewx skill tsserver references path/to/file.ts lineNumber columnNumber
52
132
 
53
133
  # If API changed, find consumers
54
- npx search "endpointName" ./src/ui --glob="**/*.ts,**/*.tsx"
134
+ crewx search "endpointName" ./src/ui --glob="**/*.ts,**/*.tsx"
55
135
 
56
136
  # If types changed, find usages
57
- npx search "typeName" ./src --glob="**/*.ts,**/*.tsx"
137
+ crewx search "typeName" ./src --glob="**/*.ts,**/*.tsx"
58
138
  ```
59
139
 
60
140
  → Fill in `api_changed`, `schema_changed`, `consumers`, `risk_level`
@@ -80,39 +160,40 @@ npx crewx skill wi draft "task description"
80
160
 
81
161
  ---
82
162
 
83
- ### issue — Issue to an agent
163
+ ### Manual procedure: issue — Issue to an agent
84
164
 
85
- Deliver an approved Work Instruction to the assigned agent.
165
+ There is no implemented CLI route for `issue`; use the procedure below to issue an approved Work Instruction.
86
166
 
87
- ```bash
88
- npx crewx skill wi issue WI-20260312-001
89
- ```
167
+ Deliver an approved Work Instruction to the assigned agent.
90
168
 
91
169
  **Issue steps:**
92
170
 
93
- 1. Read WI file → check status (must be `approved`)
171
+ 1. Read the WI file, confirm its status is `approved`, and identify its `impl_agent` before dispatching. (`consultant` is for advisory work, not an issue target.)
94
172
 
95
- 2. Check WI's `impl_agent` (`consultant` is for advisory — not an issue target)
96
-
97
- 3. Check agent memory (any in-progress work?)
173
+ 2. Check agent memory (any in-progress work?)
98
174
  ```bash
99
- npx memory index {impl_agent}
175
+ crewx memory index {impl_agent}
100
176
  ```
101
177
 
102
- 4. Issue via `$CREWX_CLI x`:
178
+ 3. Set the recipient with `--to` and send the complete WI as the body. Put a long WI in a file; its path and first line never select the recipient.
103
179
  ```bash
104
- $CREWX_CLI x "@{impl_agent} Execute Work Instruction WI-{ID}.
105
-
106
- Full WI:
107
- {entire WI file content}
180
+ crewx x --to {impl_agent} -f wi-body.md --thread="WI-{ID}" --out=".crewx/result/WI-{ID}-impl.txt"
181
+ ```
182
+ `wi-body.md` must contain the complete Work Instruction text. A bare file path as the whole prompt is insufficient.
183
+ The file supplies only the body; the recipient is specified by `--to`.
108
184
 
109
- Report in the specified format when done." \
110
- --thread="WI-{ID}" --result="WI-{ID}-impl"
185
+ For `crewx x`, `--wait` requests synchronous execution; this differs from the `--wait=N` polling limit used by `crewx result` in the next step.
186
+ 4. In agent context, the immediate task ID returned by `crewx x` is a receipt, not completion. Recover the terminal result from the foreground with:
187
+ ```bash
188
+ crewx result <task-id> --wait=N
111
189
  ```
190
+ Use `N <= 300`. Exit `124` means the task is still running, so repeat the result command using the next advised wait. Read both the terminal state (`success`, `failed`, or `stopped`) and the result body before deciding what happened; `failed` with reason `runner_lost` means the end of the run was not observed and it may still be running.
191
+
192
+ If `--out` is used in receipt mode, the output file is written when the task completes, not when the receipt is returned. Do not wrap delegation with `timeout`, `&`, `nohup`, or any other background-process ownership mechanism.
112
193
 
113
- 5. Update WI status → `in-progress`
194
+ 5. After dispatch, update WI status → `in-progress`. Only after the terminal result is available and the ACs are verified may the WI be marked `done`.
114
195
 
115
- 6. Verify AC after completion report:
196
+ 6. Verify AC after the terminal completion report:
116
197
  ```bash
117
198
  npx tsc --noEmit
118
199
  npx vitest run src/server/ # or src/ui/
@@ -122,13 +203,9 @@ npx crewx skill wi issue WI-20260312-001
122
203
 
123
204
  ---
124
205
 
125
- ### list — List WIs
206
+ ### Manual procedure: list — List WIs
126
207
 
127
- ```bash
128
- npx crewx skill wi list
129
- npx crewx skill wi list --status=approved
130
- npx crewx skill wi list --status=in-progress
131
- ```
208
+ There is no implemented CLI route for `list`; use these repository commands manually.
132
209
 
133
210
  **Execution:**
134
211
  ```bash
@@ -141,21 +218,16 @@ grep -l "status: approved" docs/wi/WI-*.md 2>/dev/null
141
218
 
142
219
  ---
143
220
 
144
- ### review — Request lead review
221
+ ### Manual procedure: review — Request lead review
145
222
 
146
- Request a review from the `consultant` before issuing.
223
+ There is no implemented CLI route for `review`; request lead review manually before issuing.
147
224
 
148
- ```bash
149
- npx crewx skill wi review WI-20260312-001
150
- ```
225
+ Request a review from the `consultant` before issuing.
151
226
 
152
227
  ```bash
153
- $CREWX_CLI q "@{consultant} Review this Work Instruction.
154
- Check feasibility, missing items, and risks.
155
-
156
- {entire WI file content}" \
157
- --thread="WI-{ID}-review" --result="WI-{ID}-review"
228
+ $CREWX_CLI q --to {consultant} -f review-body.md --thread="WI-{ID}-review" --out=".crewx/result/WI-{ID}-review.txt"
158
229
  ```
230
+ `review-body.md` must contain the review request, review criteria, and complete WI text.
159
231
 
160
232
  ---
161
233
 
@@ -208,6 +280,7 @@ When AC fails after agent completion report:
208
280
 
209
281
  ## References
210
282
 
211
- - Template: [docs/wi/WI-TEMPLATE.md](../../docs/wi/WI-TEMPLATE.md)
212
- - PM guide: [skills/pm/SKILL.md](../pm/SKILL.md)
213
- - Decomposition strategy: [docs/research/multi-agent-divide-conquer.md](../../docs/research/multi-agent-divide-conquer.md)
283
+ - Workspace WI template: `docs/wi/WI-TEMPLATE.md`
284
+ - Package-bundled seed: `packages/built-in/wi/templates/WI-TEMPLATE.md` (a separate file; these two templates are not claimed to be synchronized)
285
+ - PM guide: `skills/pm/SKILL.md`
286
+ - Decomposition strategy: `docs/research/multi-agent-divide-conquer.md`
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  export declare function main(inputArgs?: string[]): Promise<void>;
3
- //# sourceMappingURL=cli.d.ts.map
3
+
package/dist/cli.js CHANGED
@@ -1,78 +1,15 @@
1
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
2
+ "use strict";var $=exports&&exports.__createBinding||(Object.create?(function(e,t,i,s){if(s===void 0)s=i;var r=Object.getOwnPropertyDescriptor(t,i);if(!r||("get"in r?!t.__esModule:r.writable||r.configurable)){r={enumerable:true,get:function(){return t[i]}}}Object.defineProperty(e,s,r)}):(function(e,t,i,s){if(s===void 0)s=i;e[s]=t[i]}));var L=exports&&exports.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}):function(e,t){e["default"]=t});var R=exports&&exports.__importStar||(function(){var e=function(t){e=Object.getOwnPropertyNames||function(i){var s=[];for(var r in i)if(Object.prototype.hasOwnProperty.call(i,r))s[s.length]=r;return s};return e(t)};return function(t){if(t&&t.__esModule)return t;var i={};if(t!=null){for(var s=e(t),r=0;r<s.length;r++)if(s[r]!=="default")$(i,t,s[r])}L(i,t);return i}})();Object.defineProperty(exports,"__esModule",{value:true});exports.main=x;const u=R(require("fs"));const l=R(require("path"));const S=require("@crewx/shared/crewx-api-credential");const b=require("@crewx/sdk");const M=require("@crewx/sdk/repository");const O=require("@crewx/workflow/run-manager");let P="unknown";try{const e=u.existsSync(l.join(__dirname,"package.json"))?l.join(__dirname,"package.json"):l.join(__dirname,"..","package.json");const t=JSON.parse(u.readFileSync(e,"utf-8"));if(t?.version)P=String(t.version)}catch{}async function H(){try{return await Promise.resolve().then(()=>R(require("@crewx/shared/skill-tracer")))}catch{return null}}function z(){const e=l.join(__dirname,"..","SKILL.md");if(u.existsSync(e)){process.stdout.write(u.readFileSync(e,"utf-8"))}else{console.log("No SKILL.md found. Use --help for usage.")}}function E(){console.log(`
3
+ @crewx/wi@${P} - Structured task delegation via Work Instructions
70
4
 
71
5
  Usage:
72
6
  wi <command> [args]
73
7
 
74
8
  Commands:
75
9
  wi usage Show detailed guide (SKILL.md)
10
+ wi create-batch [--file <path>] Create draft WIs from batch JSON
11
+ wi board tick <brd-id> [--json] Advance one approved board WI if gates pass
12
+ wi board digest <brd-id> [--json] Send and print the overnight board summary
76
13
  wi draft <description> Draft a new Work Instruction (planned)
77
14
  wi issue <WI-ID> Issue WI to assigned agent (planned)
78
15
  wi list [--status=...] List Work Instructions (planned)
@@ -82,42 +19,8 @@ Options:
82
19
  --version Show version
83
20
  --help, -h Show this help
84
21
 
85
- Note:
86
- Phase 1 — only 'usage' is available. Other subcommands are planned.
87
-
88
22
  Template: docs/wi/WI-TEMPLATE.md
89
23
  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
24
+ `)}const K=new Set(["help","version","json"]);function G(e){const t={positional:[],options:{}};for(let i=0;i<e.length;i++){const s=e[i];if(s==="-h"){t.options["help"]=true}else if(s.startsWith("--")){const r=s.indexOf("=");if(r!==-1){t.options[s.slice(2,r)]=s.slice(r+1)}else{const a=s.slice(2);if(K.has(a)){t.options[a]=true}else{const n=e[i+1];if(n!==void 0&&!n.startsWith("--")){t.options[a]=n;i++}else{t.options[a]=true}}}}else{t.positional.push(s)}}return t}async function U(){const e=[];for await(const t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}function g(){return l.resolve(process.env["CREWX_WORKSPACE"]||process.cwd())}function X(e){const t=JSON.parse(e);if(!t||typeof t!=="object"||Array.isArray(t)){throw new Error("Input must be a JSON object")}return t}async function V(e){const t=e["file"];const i=typeof t==="string"?u.readFileSync(l.resolve(t),"utf-8"):await U();const s=X(i);const r=await(0,b.createWorkInstructionBatch)(g(),s);process.stdout.write(JSON.stringify({created:r.created.map(a=>({wi_id:a.summary.wi_id,title:a.summary.title}))})+"\n")}function F(){return{batch:{wiIds:[],approvedAt:null},chain:{state:"idle",currentWiId:null,nextWiId:null,nextTickAt:null,pauseReason:null,resumeAt:null,consecutiveFailures:0,queue:[],budget:{usedPercent:0,capPercent:70,resetsAt:null},sessionSummary:{completed:0,needsFeedback:0,failed:0,skippedTicks:0}},updatedAt:new Date().toISOString()}}function Z(e){const t=F();if(!e||typeof e!=="object")return t;const i=e;return{...t,...i,batch:{...t.batch,...i.batch??{}},chain:{...t.chain,...i.chain??{},budget:{...t.chain.budget,...i.chain?.budget??{}},sessionSummary:{...t.chain.sessionSummary,...i.chain?.sessionSummary??{}},queue:Array.isArray(i.chain?.queue)?i.chain.queue:t.chain.queue}}}function A(e){return l.join(g(),".crewx","boards",e,"state.json")}function D(e){if(!b.WI_BOARD_ID_PATTERN.test(e)){throw new Error("board id must match ^[a-zA-Z0-9_-]{1,64}$")}}function k(e){const t=A(e);if(!u.existsSync(t))return F();return Z(JSON.parse(u.readFileSync(t,"utf-8")))}function p(e,t){t.updatedAt=new Date().toISOString();const i=A(e);u.mkdirSync(l.dirname(i),{recursive:true});u.writeFileSync(i,JSON.stringify(t,null,2)+"\n","utf-8")}function Q(e){if(!e.startsWith("---"))return null;const t=e.indexOf("\n---",3);if(t===-1)return null;const i=e.indexOf("\n",t+4);return{frontmatter:e.slice(3,t).trim(),body:i===-1?"":e.slice(i+1).trim()}}function B(e){const t=e.trim();if(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")){try{return JSON.parse(t)}catch{return t.slice(1,-1)}}return t}function Y(e){const t={};const i=e.split(/\r?\n/);for(let s=0;s<i.length;s++){const r=i[s];const a=r.match(/^([A-Za-z_][\w-]*):\s*(.*)$/);if(!a)continue;const n=a[1];const o=a[2];if(o===""){const c=[];while(s+1<i.length&&/^\s+-\s+/.test(i[s+1])){s++;c.push(B(i[s].replace(/^\s+-\s+/,"")))}t[n]=c}else if(o==="[]"){t[n]=[]}else{t[n]=B(o)}}return t}function ee(e){if(Array.isArray(e))return e.map(String);if(e===void 0||e===null||e==="")return[];return[String(e)]}function C(){const e=l.join(g(),"docs","wi");if(!u.existsSync(e))return[];const t=u.readdirSync(e).filter(s=>s.endsWith(".md")&&/^WI-\d{8}-\d+/.test(s));const i=[];for(const s of t){const r=l.join(e,s);const a=u.lstatSync(r);if(!a.isFile())continue;const n=u.readFileSync(r,"utf-8");const o=Q(n);if(!o)continue;const c=Y(o.frontmatter);const f=typeof c["wi_id"]==="string"?c["wi_id"]:"";const w=typeof c["status"]==="string"?c["status"]:"draft";if(!/^WI-\d{8}-\d+$/.test(f))continue;if(!["draft","approved","in-progress","done","cancelled"].includes(w))continue;i.push({wi_id:f,title:typeof c["title"]==="string"?c["title"]:"",status:w,depends_on:ee(c["depends_on"]),assignee:typeof c["assignee"]==="string"?c["assignee"]:void 0,board:typeof c["board"]==="string"?c["board"]:void 0,source:typeof c["source"]==="string"?c["source"]:"manual",path:l.join("docs","wi",s),body:o.body})}return i}function te(){return l.join(g(),"workflows","wi-default-flow.yaml")}function j(e){return e.status==="completed"||e.status==="failed"||e.status==="cancelled"}function q(e){const t=l.join(g(),".crewx","workflow-runs");if(!u.existsSync(t))return[];const i=new Set(e);return u.readdirSync(t).filter(s=>s.endsWith(".json")).flatMap(s=>{try{const r=JSON.parse(u.readFileSync(l.join(t,s),"utf-8"));const a=typeof r.initial_state?.["wi_id"]==="string"?r.initial_state["wi_id"]:typeof r.state?.["wi_id"]==="string"?r.state["wi_id"]:"";return i.has(a)?[r]:[]}catch{return[]}})}function I(e,t){if(!e.current_node||j(e))return false;return t.getNodeType(e.workflow_file,e.workflow_id,e.current_node)==="approval"}function ne(){const e=process.env["CREWX_WI_NIGHT_START"];const t=process.env["CREWX_WI_NIGHT_END"];if(e===void 0||t===void 0)return null;const i=Number(e);const s=Number(t);if(!Number.isInteger(i)||!Number.isInteger(s))return null;if(i<0||i>23||s<0||s>23)return null;return{start:i,end:s}}function ie(e,t){if(e.start===e.end)return true;const i=t.getHours();return e.start<e.end?i>=e.start&&i<e.end:i>=e.start||i<e.end}function se(e,t){const i=new Date(t);i.setHours(e.start,0,0,0);if(i.getTime()<=t.getTime())i.setDate(i.getDate()+1);return i}function re(e,t){if(e.chain.nextTickAt){const s=Date.parse(e.chain.nextTickAt);if(!Number.isNaN(s)&&s>t.getTime()){return{paused:true,resumeAt:e.chain.nextTickAt}}}const i=ne();if(i&&!ie(i,t)){return{paused:true,resumeAt:se(i,t).toISOString()}}return{paused:false}}function v(e,t,i=new Map){e.chain.queue=e.batch.wiIds.map((s,r)=>{const a=t.some(n=>n.wi_id===s);return{wiId:s,queuePosition:r+1,blockReason:i.get(s)??(a?null:"missing")}})}const ae={codex:["fiveHour","weekly"],claude:["fiveHour","sevenDay"],glm:["fiveHour","weekly"],grok:["weekly","monthly"]};function W(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function oe(e){if(!W(e))return null;if(!Object.prototype.hasOwnProperty.call(e,"usedPercent")||!Object.prototype.hasOwnProperty.call(e,"resetsAt")){return null}const t=e["usedPercent"];const i=e["resetsAt"];if(typeof t!=="number"||!Number.isFinite(t)||t<0||t>100){return null}if(i!==null&&(typeof i!=="string"||!Number.isFinite(Date.parse(i)))){return null}return{usedPercent:t,resetsAt:i}}function ce(e){if(!W(e))return[];const t=[];for(const[i,s]of Object.entries(ae)){const r=e[i];if(!W(r))continue;if(r["status"]!=="live"&&r["status"]!=="cached")continue;if(!W(r["data"]))continue;for(const a of s){const n=oe(r["data"][a]);if(n)t.push(n)}}return t}function ue(e){const t=l.basename(e).toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"");return t||"default"}function le(){const e=g();try{const t=new M.WorkspaceRepository;const i=(0,b.hashWorkspaceId)(e);const s=t.findById(i);if(s?.slug)return s.slug;const r=t.registerWorkspace(e);if(r?.slug)return r.slug}catch{}return ue(e)}async function de(e){const t=process.env["CREWX_ENDPOINT"]??"http://localhost:8150";const i=le();const s=(0,S.resolveCrewxApiCredential)("wi");let r;try{r=await fetch(`${t}/api/v1/ws/${encodeURIComponent(i)}/usage/limits`,{headers:(0,S.authorizationHeader)(s),signal:AbortSignal.timeout(5e3)})}catch(c){return{ok:false,usedPercent:0,resetsAt:null,reason:`usage limits unavailable: ${c instanceof Error?c.message:String(c)}`}}if(!r.ok){return{ok:false,usedPercent:0,resetsAt:null,reason:`usage limits unavailable: HTTP ${r.status}`}}let a=null;try{const c=await r.json();a=W(c)?c:null}catch{}const n=ce(a?.["data"]);if(n.length===0){return{ok:false,usedPercent:0,resetsAt:null,reason:"usage limits unavailable: empty response"}}const o=n.reduce((c,f)=>f.usedPercent>c.usedPercent?f:c,n[0]);return{ok:o.usedPercent<e,usedPercent:o.usedPercent,resetsAt:o.resetsAt,...o.usedPercent>=e?{reason:`budget cap reached (${o.usedPercent}% >= ${e}%)`}:{}}}async function y(e,t){const i=process.env["CREWX_WORKSPACE"]||g();const s=process.env["CREWX_ENDPOINT"]??"http://localhost:8150";const r=(0,S.resolveCrewxApiCredential)("wi");const a={"Content-Type":"application/json",...(0,S.authorizationHeader)(r)};try{const n=await fetch(`${s}/api/v1/notifications`,{method:"POST",headers:a,body:JSON.stringify({workspace:i,title:e,level:t.level??"info",body:t.body,source:"system",metadata:t.metadata}),signal:AbortSignal.timeout(5e3)});if(!n.ok){const o=await n.text().catch(()=>"");console.error(`[wi] notification failed: HTTP ${n.status}${o?` ${o}`:""}`)}}catch(n){console.error(`[wi] notification failed: ${n instanceof Error?n.message:String(n)}`)}}async function fe(e,t){D(e);const i=new O.FileLock(A(e));try{i.acquire(100)}catch{const n={skipped:true,reason:"lock_contended"};process.stdout.write(JSON.stringify(n)+"\n");return}const s=new O.RunManager(".crewx/workflow-runs",g());let r=null;try{const n=k(e);const o=new Date;const c=re(n,o);if(c.paused){n.chain.pauseReason="time_gate";n.chain.nextTickAt=c.resumeAt;n.chain.resumeAt=c.resumeAt;n.chain.sessionSummary.skippedTicks+=1;p(e,n);process.stdout.write(JSON.stringify({skipped:true,reason:"time_gate",state:n})+"\n");return}const f=await de(n.chain.budget.capPercent);n.chain.budget.usedPercent=f.usedPercent;n.chain.budget.resetsAt=f.resetsAt;if(!f.ok){n.chain.state="limit_wait";n.chain.pauseReason=f.reason??"budget_limit";n.chain.resumeAt=f.resetsAt;n.chain.sessionSummary.skippedTicks+=1;p(e,n);process.stdout.write(JSON.stringify({skipped:true,reason:n.chain.pauseReason,state:n})+"\n");return}const w=C().filter(d=>n.batch.wiIds.includes(d.wi_id));v(n,w);const T=q(n.batch.wiIds).filter(d=>!j(d));const N=T.find(d=>!I(d,s));if(N){n.chain.state="running";n.chain.currentWiId=String(N.state?.["wi_id"]??N.initial_state?.["wi_id"]??"");n.chain.pauseReason="run_in_progress";p(e,n);process.stdout.write(JSON.stringify({skipped:true,reason:"run_in_progress",state:n})+"\n");return}const _=new Set(T.filter(d=>I(d,s)).map(d=>String(d.state?.["wi_id"]??d.initial_state?.["wi_id"]??"")));const h=(0,b.selectNextWi)(w,{batch:n.batch.wiIds,exclude:[..._]});if("blocked"in h){n.chain.state="failed_stop";n.chain.pauseReason=h.reason;v(n,w);p(e,n);await y("Board auto-run stopped",{level:"warning",body:h.reason,metadata:{boardId:e}});process.stdout.write(JSON.stringify({blocked:true,reason:h.reason,state:n})+"\n");return}if("cycle"in h){n.chain.state="failed_stop";n.chain.pauseReason=`cycle: ${h.cycle.join(", ")}`;v(n,w);p(e,n);await y("Board auto-run stopped",{level:"warning",body:n.chain.pauseReason,metadata:{boardId:e}});process.stdout.write(JSON.stringify({cycle:h.cycle,state:n})+"\n");return}if("done"in h){n.chain.state=_.size>0?"human_wait":"done";n.chain.currentWiId=null;n.chain.nextWiId=null;n.chain.pauseReason=_.size>0?"approval_wait":null;v(n,w,new Map([..._].map(d=>[d,"approval_wait"])));p(e,n);process.stdout.write(JSON.stringify({done:_.size===0,state:n})+"\n");return}const m=w.find(d=>d.wi_id===h.pick);if(!m)throw new Error(`Selected WI not found: ${h.pick}`);const J=s.start(te(),"wi-default-flow",{wi_id:m.wi_id,wi_content:m.body,assignee:m.assignee??"crewx",board_id:e});n.chain.state="running";n.chain.currentWiId=m.wi_id;n.chain.nextWiId=null;n.chain.pauseReason=null;p(e,n);r={wiId:m.wi_id,runId:J.id}}catch(n){const o=k(e);o.chain.consecutiveFailures+=1;o.chain.sessionSummary.failed+=1;o.chain.pauseReason=n instanceof Error?n.message:String(n);o.chain.state=o.chain.consecutiveFailures>=3?"failed_stop":"idle";p(e,o);if(o.chain.state==="failed_stop"){await y("Board auto-run stopped",{level:"warning",body:o.chain.pauseReason??"run_failed",metadata:{boardId:e}})}throw n}finally{i.release()}if(!r)return;let a;try{a=await s.runAuto(r.runId)}catch(n){a={run:s.loadRun(r.runId),outcome:"failed",reason:n instanceof Error?n.message:String(n),executed:[]}}i.acquire();try{const n=k(e);const o=C().filter(c=>n.batch.wiIds.includes(c.wi_id));if(a.outcome==="completed"){n.chain.state="idle";n.chain.currentWiId=null;n.chain.consecutiveFailures=0;n.chain.sessionSummary.completed+=1}else if(a.outcome==="paused"){n.chain.state=a.reason?.includes("approval node")?"human_wait":"idle";n.chain.pauseReason=a.reason??null}else if(a.outcome==="failed"){n.chain.consecutiveFailures+=1;n.chain.sessionSummary.failed+=1;n.chain.state=n.chain.consecutiveFailures>=3?"failed_stop":"idle";n.chain.pauseReason=a.reason??"run_failed";if(n.chain.state==="failed_stop"){await y("Board auto-run stopped",{level:"warning",body:n.chain.pauseReason,metadata:{boardId:e}})}}v(n,o);p(e,n);process.stdout.write(JSON.stringify({started:r.wiId,runId:r.runId,outcome:a.outcome,state:n})+"\n")}catch(n){const o=k(e);o.chain.consecutiveFailures+=1;o.chain.sessionSummary.failed+=1;o.chain.pauseReason=n instanceof Error?n.message:String(n);o.chain.state=o.chain.consecutiveFailures>=3?"failed_stop":"idle";p(e,o);if(o.chain.state==="failed_stop"){await y("Board auto-run stopped",{level:"warning",body:o.chain.pauseReason??"run_failed",metadata:{boardId:e}})}throw n}finally{i.release()}}async function pe(e,t){D(e);const i=new O.FileLock(A(e));i.acquire();try{const s=k(e);const r=new O.RunManager(".crewx/workflow-runs",g());const a=q(s.batch.wiIds).filter(n=>!j(n));s.chain.sessionSummary.needsFeedback=a.filter(n=>I(n,r)).length;p(e,s);await y("Overnight auto-run summary",{level:"info",body:JSON.stringify(s.chain.sessionSummary),metadata:{boardId:e}});process.stdout.write(JSON.stringify({boardId:e,sessionSummary:s.chain.sessionSummary,metadata:{boardId:e}})+"\n")}finally{i.release()}}async function x(e){const t=e??process.argv.slice(2);const{positional:i,options:s}=G(t);const r=i[0];if(s["version"]){console.log(P);return}if(s["help"]||r==="help"){E();return}if(r==="usage"){z();return}try{if(r==="create-batch"){await V(s);return}if(r==="board"){const a=i[1];const n=i[2];if(!n||a!=="tick"&&a!=="digest"){throw new Error("Usage: wi board <tick|digest> <brd-id>")}if(a==="tick"){await fe(n,s)}else{await pe(n,s)}return}}catch(a){if(a instanceof b.WiCreateError)throw new Error(a.message);throw a}if(r==="draft"||r==="issue"||r==="list"||r==="review"){console.log(`
25
+ '${r}' is not yet implemented.
26
+ `);console.log(" Run 'wi usage' for the full guide.\n");return}E()}if(typeof require!=="undefined"&&require.main===module){H().then(e=>{const t=e?{skillVersion:e.getOwnSkillVersion(__dirname)}:{};return e?e.run("crewx/wi",()=>x(),t):x()}).catch(e=>{console.error(e.message);process.exit(e instanceof S.CrewxCredentialError?e.exitCode:1)})}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewx/wi",
3
- "version": "0.1.10-rc.19",
3
+ "version": "0.1.10-rc.190",
4
4
  "description": "Work Instruction engine for CrewX - structured task delegation",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cli.js",
@@ -25,9 +25,21 @@
25
25
  "templates/"
26
26
  ],
27
27
  "dependencies": {
28
- "@crewx/shared": "0.0.6-rc.6"
28
+ "@crewx/sdk": "0.9.0-rc.170",
29
+ "@crewx/shared": "0.0.6-rc.85",
30
+ "@crewx/workflow": "0.3.22-rc.216"
31
+ },
32
+ "peerDependencies": {
33
+ "better-sqlite3": ">=12.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "better-sqlite3": {
37
+ "optional": true
38
+ }
29
39
  },
30
40
  "devDependencies": {
41
+ "@types/better-sqlite3": "*",
42
+ "better-sqlite3": "12.8.0",
31
43
  "@types/node": "^20.0.0",
32
44
  "typescript": "^5.0.0"
33
45
  },
package/dist/cli.d.ts.map DELETED
@@ -1 +0,0 @@
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.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}