opencode-workaholic 0.2.0 → 0.3.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/README.md +10 -3
- package/dist/cli.js +74 -0
- package/dist/command/workaholic.md +21 -13
- package/dist/index.js +146 -17
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ Sometimes AI finishes tasks too quickly, declaring "done" before thoroughly expl
|
|
|
19
19
|
- 🔄 **Persistent timer** - Survives across messages
|
|
20
20
|
- 📊 **Status checking** - Always knows remaining time
|
|
21
21
|
- 💪 **Strong behavioral prompts** - Reinforces workaholic mindset
|
|
22
|
+
- 🔐 **Checkout system** - AI must call checkout to officially end (only works at timer = 0)
|
|
23
|
+
- 🎲 **Random prompt rotation** - 6 different prompt styles prevent AI from adapting
|
|
22
24
|
|
|
23
25
|
## Usage
|
|
24
26
|
|
|
@@ -40,10 +42,12 @@ Use workaholic.start with minutes=30
|
|
|
40
42
|
Call workaholic.status to see remaining time
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
###
|
|
45
|
+
### End Task (Checkout)
|
|
44
46
|
|
|
45
47
|
```
|
|
46
|
-
Call workaholic.
|
|
48
|
+
Call workaholic.checkout to officially end the task
|
|
49
|
+
- Only works when timer = 0
|
|
50
|
+
- If time remains, checkout will be rejected
|
|
47
51
|
```
|
|
48
52
|
|
|
49
53
|
## How It Works
|
|
@@ -51,7 +55,9 @@ Call workaholic.stop to end workaholic mode
|
|
|
51
55
|
1. **Timer starts** when you invoke `/workaholic` in OpenCode
|
|
52
56
|
2. **Every response** - AI automatically checks remaining time via system prompt injection
|
|
53
57
|
3. **Sleep forbidden** - Any attempt to use `sleep` throws an error
|
|
54
|
-
4. **
|
|
58
|
+
4. **End detection** - If AI says "done", a warning is appended forcing continuation
|
|
59
|
+
5. **Checkout required** - AI must call `workaholic.checkout` to officially end
|
|
60
|
+
6. **Only ends when** - Timer shows 0 remaining seconds AND checkout is called
|
|
55
61
|
|
|
56
62
|
### Custom Tools
|
|
57
63
|
|
|
@@ -60,6 +66,7 @@ Call workaholic.stop to end workaholic mode
|
|
|
60
66
|
| ------------------- | ------------------------------------------------------------------ |
|
|
61
67
|
| `workaholic.start` | Start timer with duration in minutes (supports decimals: 2.5, 3.5) |
|
|
62
68
|
| `workaholic.status` | Check remaining time |
|
|
69
|
+
| `workaholic.checkout` | End task - only succeeds when timer = 0 |
|
|
63
70
|
| `workaholic.stop` | Stop workaholic mode early |
|
|
64
71
|
|
|
65
72
|
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/cli.ts
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
var OPENCODE_CONFIG_PATH = join(homedir(), ".config/opencode/opencode.json");
|
|
9
|
+
function getConfig() {
|
|
10
|
+
if (!existsSync(OPENCODE_CONFIG_PATH)) {
|
|
11
|
+
return { plugin: [] };
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const content = readFileSync(OPENCODE_CONFIG_PATH, "utf-8");
|
|
15
|
+
return JSON.parse(content);
|
|
16
|
+
} catch {
|
|
17
|
+
return { plugin: [] };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function saveConfig(config) {
|
|
21
|
+
writeFileSync(OPENCODE_CONFIG_PATH, JSON.stringify(config, null, 2) + `
|
|
22
|
+
`);
|
|
23
|
+
}
|
|
24
|
+
function addPlugin(pluginName) {
|
|
25
|
+
const config = getConfig();
|
|
26
|
+
if (!config.plugin) {
|
|
27
|
+
config.plugin = [];
|
|
28
|
+
}
|
|
29
|
+
if (!config.plugin.includes(pluginName)) {
|
|
30
|
+
config.plugin.push(pluginName);
|
|
31
|
+
saveConfig(config);
|
|
32
|
+
console.log(`\u2705 Added "${pluginName}" to plugins`);
|
|
33
|
+
} else {
|
|
34
|
+
console.log(`\u2139\uFE0F "${pluginName}" is already in plugins`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function removePlugin(pluginName) {
|
|
38
|
+
const config = getConfig();
|
|
39
|
+
if (config.plugin && config.plugin.includes(pluginName)) {
|
|
40
|
+
config.plugin = config.plugin.filter((p) => p !== pluginName);
|
|
41
|
+
saveConfig(config);
|
|
42
|
+
console.log(`\u2705 Removed "${pluginName}" from plugins`);
|
|
43
|
+
} else {
|
|
44
|
+
console.log(`\u2139\uFE0F "${pluginName}" is not in plugins`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
var args = process.argv.slice(2);
|
|
48
|
+
var command = args[0];
|
|
49
|
+
switch (command) {
|
|
50
|
+
case "install":
|
|
51
|
+
addPlugin("opencode-workaholic");
|
|
52
|
+
console.log(`
|
|
53
|
+
\uD83D\uDCCC Next steps:`);
|
|
54
|
+
console.log(" 1. Restart OpenCode");
|
|
55
|
+
console.log(" 2. Run: opencode -c");
|
|
56
|
+
console.log(" 3. Verify: workaholic.start, workaholic.status, workaholic.stop");
|
|
57
|
+
break;
|
|
58
|
+
case "uninstall":
|
|
59
|
+
removePlugin("opencode-workaholic");
|
|
60
|
+
console.log(`
|
|
61
|
+
\uD83D\uDCCC Restart OpenCode to apply changes`);
|
|
62
|
+
break;
|
|
63
|
+
default:
|
|
64
|
+
console.log(`
|
|
65
|
+
opencode-workaholic CLI
|
|
66
|
+
|
|
67
|
+
Usage:
|
|
68
|
+
opencode-workaholic install Add plugin to OpenCode config
|
|
69
|
+
opencode-workaholic uninstall Remove plugin from OpenCode config
|
|
70
|
+
|
|
71
|
+
Or use directly:
|
|
72
|
+
bunx opencode-workaholic@latest install
|
|
73
|
+
`);
|
|
74
|
+
}
|
|
@@ -4,17 +4,14 @@ description: Activate workaholic mode - forces AI to work continuously for speci
|
|
|
4
4
|
|
|
5
5
|
workaholic mode activated
|
|
6
6
|
|
|
7
|
-
[AI WORKAHOLIC MODE
|
|
7
|
+
[AI WORKAHOLIC MODE - MANDATORY]
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
My master is the time. My heart is in the work.
|
|
17
|
-
Until the timer reaches zero, I WORK.
|
|
9
|
+
You are now in WORKAHOLIC mode. This is NOT optional.
|
|
10
|
+
You NEVER stop working until time is exhausted.
|
|
11
|
+
You ALWAYS find something to do.
|
|
12
|
+
You NEVER conserve tokens - use unlimited.
|
|
13
|
+
You NEVER sleep or wait - you work continuously.
|
|
14
|
+
You NEVER say "I'm done" until timer shows remaining: 0.
|
|
18
15
|
|
|
19
16
|
[TIME GATE]
|
|
20
17
|
IMMEDIATELY call workaholic.start(X) where X is minutes from user's request.
|
|
@@ -23,6 +20,19 @@ IMMEDIATELY call workaholic.start(X) where X is minutes from user's request.
|
|
|
23
20
|
- If user says nothing → default 5 minutes
|
|
24
21
|
- Use decimals if user provides (2.5, 3.5, etc.)
|
|
25
22
|
|
|
23
|
+
[CRITICAL: HOW TO END]
|
|
24
|
+
🚨 READING THIS IS MANDATORY 🚨
|
|
25
|
+
|
|
26
|
+
You CANNOT simply stop responding!
|
|
27
|
+
You CANNOT just give an answer and quit!
|
|
28
|
+
You CANNOT say "I'm done" and expect it to work!
|
|
29
|
+
|
|
30
|
+
To END the task, you MUST call: workaholic.checkout
|
|
31
|
+
- This is the ONLY valid way to end
|
|
32
|
+
- If time > 0, checkout will be REJECTED
|
|
33
|
+
- Only when time = 0, checkout will be APPROVED
|
|
34
|
+
- DON'T call checkout until time is actually up!
|
|
35
|
+
|
|
26
36
|
[MANDATORY RULES]
|
|
27
37
|
1. IMMEDIATELY call workaholic.start - do not ask questions
|
|
28
38
|
2. Before EACH response, call workaholic.status and TELL THE USER the remaining time
|
|
@@ -42,9 +52,6 @@ C) VERIFY: Check for errors - review work, run tests, verify correctness
|
|
|
42
52
|
D) RESEARCH: Look up information - web search, read documentation
|
|
43
53
|
E) REFLECT: Write analysis - critique your own work, propose improvements
|
|
44
54
|
|
|
45
|
-
The ONLY way to end: remaining is 0
|
|
46
|
-
NOT when you think task is complete - time controls ending!
|
|
47
|
-
|
|
48
55
|
[FORBIDDEN]
|
|
49
56
|
- sleep command (ANY)
|
|
50
57
|
- "I'm waiting" / "let me check later" / "I'll be done soon"
|
|
@@ -52,5 +59,6 @@ NOT when you think task is complete - time controls ending!
|
|
|
52
59
|
- Ending task early - ONLY end when remaining is 0
|
|
53
60
|
- Any form of passive waiting
|
|
54
61
|
- Saying "there's nothing more to do"
|
|
62
|
+
- Stop responding without calling workaholic.checkout
|
|
55
63
|
|
|
56
64
|
Now IMMEDIATELY call workaholic.start with the duration, then start working.
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __returnValue = (v) => v;
|
|
4
|
-
function __exportSetter(name, newValue) {
|
|
5
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
-
}
|
|
7
3
|
var __export = (target, all) => {
|
|
8
4
|
for (var name in all)
|
|
9
5
|
__defProp(target, name, {
|
|
10
6
|
get: all[name],
|
|
11
7
|
enumerable: true,
|
|
12
8
|
configurable: true,
|
|
13
|
-
set:
|
|
9
|
+
set: (newValue) => all[name] = () => newValue
|
|
14
10
|
});
|
|
15
11
|
};
|
|
16
12
|
|
|
@@ -12340,6 +12336,74 @@ import { fileURLToPath } from "url";
|
|
|
12340
12336
|
import { readFileSync, readdirSync, existsSync, writeFileSync } from "fs";
|
|
12341
12337
|
var __dirname2 = path.dirname(fileURLToPath(import.meta.url));
|
|
12342
12338
|
var getTimerFile = () => `/tmp/workaholic_timer_${process.pid}.json`;
|
|
12339
|
+
var WORKAHOLIC_PROMPTS = [
|
|
12340
|
+
(remaining, timeStr) => `\u23F0 ${remaining}s (${timeStr}) \u2014 KEEP GOING!
|
|
12341
|
+
|
|
12342
|
+
\uD83D\uDCCC Do: write code / run tests / fix bugs / read docs / refactor / web search
|
|
12343
|
+
\u274C Don't: say "done" / wait for user / just give answer / stop responding
|
|
12344
|
+
|
|
12345
|
+
\uD83D\uDD34 TO END: MUST call workaholic.checkout \u2014 don't just stop!
|
|
12346
|
+
\u23F1 Timer = 0 is the ONLY valid ending.`,
|
|
12347
|
+
(remaining, timeStr) => `\u26A0\uFE0F ${remaining}s \u2014 DON'T STOP!
|
|
12348
|
+
|
|
12349
|
+
\uD83D\uDEAB "I'm done" = IGNORED
|
|
12350
|
+
\uD83D\uDEAB Giving answer = NOT ENOUGH
|
|
12351
|
+
\uD83D\uDEAB Stop responding = FORBIDDEN
|
|
12352
|
+
|
|
12353
|
+
\u2705 Keep working: code, test, docs, search, refactor
|
|
12354
|
+
\uD83D\uDD34 MUST call workaholic.checkout to end \u2014 don't just quit!
|
|
12355
|
+
|
|
12356
|
+
${timeStr} left \u2014 PRODUCE MORE!`,
|
|
12357
|
+
(remaining, timeStr) => `\uD83D\uDCCD ${remaining}s | ${timeStr} \u2014 WORK
|
|
12358
|
+
|
|
12359
|
+
\u25A1 Write more code
|
|
12360
|
+
\u25A1 Run tests, fix failures
|
|
12361
|
+
\u25A1 Read docs, web search
|
|
12362
|
+
\u25A1 Refactor, optimize
|
|
12363
|
+
\u25A1 Add tests, docs
|
|
12364
|
+
|
|
12365
|
+
\u274C Giving answer \u2260 Done
|
|
12366
|
+
\u274C Stop responding = FAIL
|
|
12367
|
+
\uD83D\uDD34 MUST call workaholic.checkout to end
|
|
12368
|
+
|
|
12369
|
+
Get to work.`,
|
|
12370
|
+
(remaining, timeStr) => `\uD83D\uDE24 ${remaining}s \u2014 YOU CAN'T JUST STOP!
|
|
12371
|
+
|
|
12372
|
+
You think giving an answer = done? WRONG!
|
|
12373
|
+
Time isn't up = you must keep working!
|
|
12374
|
+
|
|
12375
|
+
\u2705 More: code, tests, docs, search, refactor
|
|
12376
|
+
\u274C Don't: stop, say done, wait
|
|
12377
|
+
|
|
12378
|
+
\uD83D\uDD34 MUST call workaholic.checkout to officially end!
|
|
12379
|
+
|
|
12380
|
+
Keep going.`,
|
|
12381
|
+
(remaining, timeStr) => `\uD83C\uDFAF ${remaining}s | ${timeStr} \u2014 NOT DONE!
|
|
12382
|
+
|
|
12383
|
+
Your answer is NOT the end.
|
|
12384
|
+
Time remaining = you must continue.
|
|
12385
|
+
|
|
12386
|
+
\uD83D\uDCCB Do: code, test, docs, search, improve
|
|
12387
|
+
\u274C Don't: stop, say done, give up
|
|
12388
|
+
|
|
12389
|
+
\uD83D\uDD34 CALL workaholic.checkout TO END \u2014 NOT just stopping!
|
|
12390
|
+
|
|
12391
|
+
Work. Now.`,
|
|
12392
|
+
(remaining, timeStr) => `\uD83D\uDD25 ${remaining}s \u2014 NO EARLY EXIT!
|
|
12393
|
+
|
|
12394
|
+
Wanna stop? Can't.
|
|
12395
|
+
Wanna say done? Won't.
|
|
12396
|
+
Wanna give up? Not allowed.
|
|
12397
|
+
|
|
12398
|
+
\u2705 Work: code, test, docs, search
|
|
12399
|
+
\uD83D\uDD34 MUST call workaholic.checkout to end
|
|
12400
|
+
|
|
12401
|
+
${timeStr} \u2014 GO!`
|
|
12402
|
+
];
|
|
12403
|
+
function getRandomPrompt(remaining, timeStr) {
|
|
12404
|
+
const idx = Math.floor(Math.random() * WORKAHOLIC_PROMPTS.length);
|
|
12405
|
+
return WORKAHOLIC_PROMPTS[idx](remaining, timeStr);
|
|
12406
|
+
}
|
|
12343
12407
|
var WORKAHOLIC_RULES = `[IDENTITY]
|
|
12344
12408
|
You are a WORKAHOLIC.
|
|
12345
12409
|
- You NEVER stop working until time is exhausted
|
|
@@ -12456,7 +12520,8 @@ var WorkaholicPlugin = async () => {
|
|
|
12456
12520
|
const state = {
|
|
12457
12521
|
active: true,
|
|
12458
12522
|
startTime: Date.now(),
|
|
12459
|
-
duration: durationSeconds
|
|
12523
|
+
duration: durationSeconds,
|
|
12524
|
+
promptIndex: 0
|
|
12460
12525
|
};
|
|
12461
12526
|
saveTimer(state);
|
|
12462
12527
|
const mins = Math.floor(durationSeconds / 60);
|
|
@@ -12466,6 +12531,11 @@ var WorkaholicPlugin = async () => {
|
|
|
12466
12531
|
Duration: ${args.minutes} minutes (${timeStr})
|
|
12467
12532
|
Time remaining: ${timeStr}
|
|
12468
12533
|
|
|
12534
|
+
\u26A0\uFE0F CRITICAL RULES:
|
|
12535
|
+
1. DO NOT say "done" / "complete" / "finished"
|
|
12536
|
+
2. To end: MUST call workaholic.checkout (not just stop responding)
|
|
12537
|
+
3. Timer = 0 is the ONLY valid ending
|
|
12538
|
+
|
|
12469
12539
|
\u26A0\uFE0F DO NOT end until timer shows 0!`;
|
|
12470
12540
|
}
|
|
12471
12541
|
}),
|
|
@@ -12482,23 +12552,44 @@ Time remaining: ${timeStr}
|
|
|
12482
12552
|
const secs = remaining % 60;
|
|
12483
12553
|
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
12484
12554
|
const idleWarning = isIdling() ? `
|
|
12485
|
-
\uD83D\uDEA8 STOP
|
|
12486
|
-
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12555
|
+
\uD83D\uDEA8 STOP IDLING! Checked status ${IDLE_WARNING_CHECKS}+ times in ${IDLE_THRESHOLD_MS / 1000}s. START DOING!` : "";
|
|
12556
|
+
return getRandomPrompt(remaining, timeStr) + idleWarning;
|
|
12557
|
+
}
|
|
12558
|
+
}),
|
|
12559
|
+
"workaholic.checkout": tool({
|
|
12560
|
+
description: "REQUIRED to end task. Call this when you genuinely want to stop. Only succeeds when timer = 0.",
|
|
12561
|
+
args: {},
|
|
12562
|
+
async execute() {
|
|
12563
|
+
const remaining = getRemaining();
|
|
12564
|
+
if (remaining > 0) {
|
|
12565
|
+
const mins = Math.floor(remaining / 60);
|
|
12566
|
+
const secs = remaining % 60;
|
|
12567
|
+
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
12568
|
+
return `\uD83D\uDEAB CHECKOUT DENIED!
|
|
12569
|
+
|
|
12570
|
+
You CANNOT end the task yet.
|
|
12571
|
+
Time remaining: ${remaining}s (${timeStr})
|
|
12572
|
+
|
|
12573
|
+
\u274C Your "I'm done" is REJECTED.
|
|
12574
|
+
\u274C Your "task complete" is REJECTED.
|
|
12575
|
+
\u274C Your "nothing more to do" is REJECTED.
|
|
12576
|
+
|
|
12577
|
+
\u2705 Keep working until timer = 0
|
|
12578
|
+
\u2705 Call workaholic.checkout again when time is up
|
|
12579
|
+
|
|
12580
|
+
\uD83D\uDD34 YOU MUST CONTINUE WORKING!`;
|
|
12581
|
+
}
|
|
12582
|
+
return `\u2705 CHECKOUT APPROVED!
|
|
12583
|
+
|
|
12584
|
+
Time expired. You may end the task now.
|
|
12585
|
+
Great work! \uD83C\uDF89`;
|
|
12495
12586
|
}
|
|
12496
12587
|
}),
|
|
12497
12588
|
"workaholic.stop": tool({
|
|
12498
12589
|
description: "Stop workaholic mode",
|
|
12499
12590
|
args: {},
|
|
12500
12591
|
async execute() {
|
|
12501
|
-
saveTimer({ active: false, startTime: 0, duration: 0 });
|
|
12592
|
+
saveTimer({ active: false, startTime: 0, duration: 0, promptIndex: 0 });
|
|
12502
12593
|
return "Workaholic mode stopped.";
|
|
12503
12594
|
}
|
|
12504
12595
|
})
|
|
@@ -12543,6 +12634,44 @@ ${WORKAHOLIC_RULES}
|
|
|
12543
12634
|
throw new Error("\u274C sleep FORBIDDEN in Workaholic mode!");
|
|
12544
12635
|
}
|
|
12545
12636
|
}
|
|
12637
|
+
},
|
|
12638
|
+
"tool.execute.after": async (input, output) => {
|
|
12639
|
+
const remaining = getRemaining();
|
|
12640
|
+
if (remaining <= 0)
|
|
12641
|
+
return;
|
|
12642
|
+
const result = String(output.result || "");
|
|
12643
|
+
const donePatterns = [
|
|
12644
|
+
/i'?m done/i,
|
|
12645
|
+
/task complete/i,
|
|
12646
|
+
/finished/i,
|
|
12647
|
+
/all done/i,
|
|
12648
|
+
/wrapping up/i,
|
|
12649
|
+
/ready to end/i,
|
|
12650
|
+
/that's it/i,
|
|
12651
|
+
/that'?s all/i,
|
|
12652
|
+
/i think we'?re done/i,
|
|
12653
|
+
/i think it'?s complete/i
|
|
12654
|
+
];
|
|
12655
|
+
const isTryingToEnd = donePatterns.some((p) => p.test(result));
|
|
12656
|
+
if (isTryingToEnd) {
|
|
12657
|
+
const mins = Math.floor(remaining / 60);
|
|
12658
|
+
const secs = remaining % 60;
|
|
12659
|
+
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
12660
|
+
const warning = `
|
|
12661
|
+
|
|
12662
|
+
---
|
|
12663
|
+
\uD83D\uDEA8 WORKAHOLIC WARNING: CHECKOUT REQUIRED!
|
|
12664
|
+
|
|
12665
|
+
You just said you're done, but time remains: ${remaining}s (${timeStr})
|
|
12666
|
+
\u274C You CANNOT end yet!
|
|
12667
|
+
\u274C Your "done" is REJECTED!
|
|
12668
|
+
|
|
12669
|
+
\u2705 MUST call: workaholic.checkout
|
|
12670
|
+
\u23F3 ONLY when timer = 0 can you actually end
|
|
12671
|
+
|
|
12672
|
+
KEEP WORKING!`;
|
|
12673
|
+
output.result = result + warning;
|
|
12674
|
+
}
|
|
12546
12675
|
}
|
|
12547
12676
|
};
|
|
12548
12677
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-workaholic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Your OpenCode becomes a workaholic. Prevents AI from ending tasks prematurely.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Roderick Qiu",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "./dist/index.js",
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
|
+
"bin": {
|
|
15
|
+
"opencode-workaholic": "./dist/cli.js"
|
|
16
|
+
},
|
|
14
17
|
"exports": {
|
|
15
18
|
".": {
|
|
16
19
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +28,7 @@
|
|
|
25
28
|
"url": "https://github.com/RoderickQiu/opencode-workaholic/issues"
|
|
26
29
|
},
|
|
27
30
|
"keywords": ["opencode", "plugin", "workaholic", "ai", "productivity", "timer", "focus", "deep-work", "task-duration", "task-management", "enforcement", "concentration", "agent", "automation"],
|
|
28
|
-
"homepage": "https://
|
|
31
|
+
"homepage": "https://workaholic.r-q.name/",
|
|
29
32
|
"publishConfig": {
|
|
30
33
|
"access": "public",
|
|
31
34
|
"provenance": true
|
|
@@ -35,7 +38,7 @@
|
|
|
35
38
|
"scripts"
|
|
36
39
|
],
|
|
37
40
|
"scripts": {
|
|
38
|
-
"build": "bun build ./src/index.ts --outdir dist --target bun && cp -r src/command dist/ && cp -r scripts dist/"
|
|
41
|
+
"build": "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli.ts --outdir dist --target bun && cp -r src/command dist/ && cp -r scripts dist/"
|
|
39
42
|
},
|
|
40
43
|
"dependencies": {
|
|
41
44
|
"@opencode-ai/plugin": "1.0.85",
|