@icaruk/zai-peak-hours 0.1.1 → 0.4.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 CHANGED
@@ -7,8 +7,7 @@ OpenCode plugin that displays z.ai peak hours information with automatic timezon
7
7
  - 🌍 Automatic timezone detection (UTC+8 / Asia/Shanghai)
8
8
  - ⏰ Real-time peak hours status (14:00-18:00 UTC+8)
9
9
  - 📊 Time remaining until next peak/off-peak transition
10
- - 🔔 Toast notification on session start
11
- - 💬 Zero-token commands (`/peak_hours`, `/peak_hours_status`) - no LLM invocation
10
+ - 💬 Zero-token slash commands (`/peak_hours`, `/peak_hours_status`) - no LLM invocation
12
11
 
13
12
  ## Installation
14
13
 
@@ -31,20 +30,6 @@ Commands are automatically available after plugin installation:
31
30
 
32
31
  These commands execute locally without invoking LLM (zero token usage) via `command.execute.before` hook.
33
32
 
34
- ## Messages
35
-
36
- The plugin displays a toast notification when a new session is created:
37
-
38
- **Peak Hours:**
39
- ```
40
- Currently in peak hours. X hours Y minutes remaining
41
- ```
42
-
43
- **Off-Peak Hours:**
44
- ```
45
- Currently in off-peak hours. X hours Y minutes remaining
46
- ```
47
-
48
33
  ## Configuration
49
34
 
50
35
  Optional configuration file at `~/.config/opencode/peak-hours.json`:
package/dist/config.d.ts CHANGED
@@ -2,3 +2,4 @@ export interface PluginConfig {
2
2
  enabled: boolean;
3
3
  }
4
4
  export declare const DEFAULT_CONFIG: PluginConfig;
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,YAE5B,CAAC"}
package/dist/config.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export const DEFAULT_CONFIG = {
2
2
  enabled: true
3
3
  };
4
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,OAAO,EAAE,IAAI;CACd,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { PeakHoursPlugin } from "./plugin.js";
2
- export type { PeakHoursStatus, } from "./peak-hours.js";
1
+ import type { Plugin } from '@opencode-ai/plugin';
2
+ export declare const PeakHours: Plugin;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAqFlD,eAAO,MAAM,SAAS,EAAE,MA+EvB,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1,127 @@
1
- export { PeakHoursPlugin } from "./plugin.js";
1
+ import { getPeakHoursStatus, formatPeakHoursMessage } from './utils.js';
2
+ import { DEFAULT_CONFIG } from './config.js';
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ // Command-handled sentinel
6
+ const COMMAND_HANDLED_SENTINEL = '__PEAK_HOURS_COMMAND_HANDLED__';
7
+ function handled() {
8
+ throw new Error(COMMAND_HANDLED_SENTINEL);
9
+ }
10
+ function getConfigPath() {
11
+ const configDir = process.env.XDG_CONFIG_HOME
12
+ ? path.join(process.env.XDG_CONFIG_HOME, 'opencode')
13
+ : path.join(process.env.HOME || process.env.USERPROFILE || '', '.config', 'opencode');
14
+ return path.join(configDir, 'peak-hours.json');
15
+ }
16
+ function loadConfig() {
17
+ const configPath = getConfigPath();
18
+ if (fs.existsSync(configPath)) {
19
+ try {
20
+ const configContent = fs.readFileSync(configPath, 'utf-8');
21
+ const userConfig = JSON.parse(configContent);
22
+ return {
23
+ enabled: userConfig.enabled !== undefined ? userConfig.enabled : DEFAULT_CONFIG.enabled,
24
+ };
25
+ }
26
+ catch (error) {
27
+ console.error('Error loading peak-hours config:', error);
28
+ }
29
+ }
30
+ return DEFAULT_CONFIG;
31
+ }
32
+ function renderCommandHeading(title) {
33
+ return `${title}\n${'='.repeat(title.length)}`;
34
+ }
35
+ function renderStatusReport(status, config) {
36
+ const currentTime = new Date().toISOString();
37
+ const lines = [
38
+ renderCommandHeading('Peak Hours Status'),
39
+ '',
40
+ 'Configuration:',
41
+ `- enabled: ${config.enabled}`,
42
+ '',
43
+ 'Current Status:',
44
+ `- current_time: ${currentTime}`,
45
+ `- in_peak_hours: ${status.inPeakHours}`,
46
+ `- transition: ${status.transitionType}`,
47
+ `- time_until_${status.transitionType}: ${status.timeUntilTransition}`,
48
+ '',
49
+ 'Peak Hours (UTC+8):',
50
+ `- start: 14:00`,
51
+ `- end: 18:00`,
52
+ ];
53
+ return lines.join('\n');
54
+ }
55
+ export const PeakHours = async ({ client }) => {
56
+ const config = loadConfig();
57
+ const typedClient = client;
58
+ async function injectRawOutput(sessionID, output) {
59
+ try {
60
+ await typedClient.session.prompt({
61
+ path: { id: sessionID },
62
+ body: {
63
+ noReply: true,
64
+ parts: [{ type: 'text', text: output, ignored: true }],
65
+ },
66
+ });
67
+ }
68
+ catch (err) {
69
+ console.error('Failed to inject output:', err);
70
+ }
71
+ }
72
+ async function injectCommandOutputAndHandle(sessionID, output) {
73
+ if (output !== undefined && output !== null) {
74
+ await injectRawOutput(sessionID, output);
75
+ }
76
+ handled();
77
+ }
78
+ async function handlePeakHoursSlashCommand(input) {
79
+ if (!config.enabled) {
80
+ return await injectCommandOutputAndHandle(input.sessionID, 'Peak Hours plugin is disabled');
81
+ }
82
+ const status = getPeakHoursStatus();
83
+ const output = formatPeakHoursMessage(status);
84
+ return await injectCommandOutputAndHandle(input.sessionID, output);
85
+ }
86
+ async function handlePeakHoursStatusSlashCommand(input) {
87
+ if (!config.enabled) {
88
+ return await injectCommandOutputAndHandle(input.sessionID, 'Peak Hours plugin is disabled');
89
+ }
90
+ const status = getPeakHoursStatus();
91
+ const output = renderStatusReport(status, config);
92
+ return await injectCommandOutputAndHandle(input.sessionID, output);
93
+ }
94
+ return {
95
+ // Register built-in slash commands
96
+ config: async (input) => {
97
+ const cfg = input;
98
+ cfg.command ??= {};
99
+ cfg.command['peak_hours'] = {
100
+ template: '/peak_hours',
101
+ description: 'Display current z.ai peak hours status and time until next transition',
102
+ };
103
+ cfg.command['peak_hours_status'] = {
104
+ template: '/peak_hours_status',
105
+ description: 'Display peak hours plugin diagnostics and configuration status',
106
+ };
107
+ },
108
+ // Intercept slash commands and handle them without LLM invocation
109
+ 'command.execute.before': async (input) => {
110
+ try {
111
+ const cmd = input.command;
112
+ if (cmd === 'peak_hours') {
113
+ return await handlePeakHoursSlashCommand(input);
114
+ }
115
+ if (cmd === 'peak_hours_status') {
116
+ return await handlePeakHoursStatusSlashCommand(input);
117
+ }
118
+ }
119
+ catch (err) {
120
+ // IMPORTANT: do not swallow command-handled sentinel errors.
121
+ // If this hook resolves, the command proceeds to the LLM.
122
+ throw err;
123
+ }
124
+ },
125
+ };
126
+ };
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -5,3 +5,4 @@ export interface PeakHoursStatus {
5
5
  }
6
6
  export declare function getPeakHoursStatus(): PeakHoursStatus;
7
7
  export declare function formatPeakHoursMessage(status: PeakHoursStatus): string;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,OAAO,GAAG,KAAK,CAAC;CACjC;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAkDpD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAMtE"}
@@ -52,3 +52,4 @@ export function formatPeakHoursMessage(status) {
52
52
  return `Currently in off-peak hours. ${status.timeUntilTransition} remaining`;
53
53
  }
54
54
  }
55
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,kBAAkB;IAChC,MAAM,cAAc,GAAG,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,EAAE,CAAC;IAExB,iDAAiD;IACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,iBAAiB,EAAE,GAAG,KAAK,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAEzC,IAAI,WAAoB,CAAC;IACzB,IAAI,cAAoB,CAAC;IACzB,IAAI,cAA+B,CAAC;IAEpC,IAAI,WAAW,IAAI,cAAc,IAAI,WAAW,GAAG,YAAY,EAAE,CAAC;QAChE,WAAW,GAAG,IAAI,CAAC;QACnB,cAAc,GAAG,KAAK,CAAC;QACvB,cAAc,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,cAAc,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,KAAK,CAAC;QACpB,cAAc,GAAG,OAAO,CAAC;QAEzB,IAAI,aAAa,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;YAChC,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,aAAa,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,cAAc,GAAG,aAAa,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAEtE,IAAI,mBAA2B,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAC7B,mBAAmB,GAAG,GAAG,KAAK,UAAU,OAAO,UAAU,CAAC;IAC5D,CAAC;SAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrB,mBAAmB,GAAG,GAAG,KAAK,QAAQ,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,mBAAmB,GAAG,GAAG,OAAO,UAAU,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,WAAW;QACX,mBAAmB;QACnB,cAAc;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAuB;IAC5D,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO,4BAA4B,MAAM,CAAC,mBAAmB,YAAY,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,OAAO,gCAAgC,MAAM,CAAC,mBAAmB,YAAY,CAAC;IAChF,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icaruk/zai-peak-hours",
3
- "version": "0.1.1",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin to display z.ai peak hours information with automatic timezone detection",
6
6
  "main": "dist/index.js",
@@ -25,8 +25,8 @@
25
25
  ],
26
26
  "author": "Icaruk",
27
27
  "license": "MIT",
28
- "dependencies": {
29
- "@opencode-ai/plugin": "^1.4.3"
28
+ "peerDependencies": {
29
+ "@opencode-ai/plugin": "^1.4.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^20.0.0",
@@ -39,6 +39,9 @@
39
39
  ],
40
40
  "repository": {
41
41
  "type": "git",
42
- "url": "https://github.com/Icaruk/zai-peak-hours.git"
42
+ "url": "git+https://github.com/Icaruk/zai-peak-hours.git"
43
+ },
44
+ "engines": {
45
+ "node": ">=18.0.0"
43
46
  }
44
47
  }
@@ -1,2 +0,0 @@
1
- export declare const COMMAND_HANDLED_SENTINEL: "__PEAK_HOURS_COMMAND_HANDLED__";
2
- export declare function handled(): never;
@@ -1,4 +0,0 @@
1
- export const COMMAND_HANDLED_SENTINEL = "__PEAK_HOURS_COMMAND_HANDLED__";
2
- export function handled() {
3
- throw new Error(COMMAND_HANDLED_SENTINEL);
4
- }
package/dist/plugin.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { Plugin } from '@opencode-ai/plugin';
2
- export declare const PeakHoursPlugin: Plugin;
package/dist/plugin.js DELETED
@@ -1,90 +0,0 @@
1
- import { getPeakHoursStatus, formatPeakHoursMessage } from './peak-hours';
2
- import { DEFAULT_CONFIG } from './config';
3
- import * as fs from 'node:fs';
4
- import * as path from 'node:path';
5
- function getConfigPath() {
6
- const configDir = process.env.XDG_CONFIG_HOME
7
- ? path.join(process.env.XDG_CONFIG_HOME, 'opencode')
8
- : path.join(process.env.HOME || process.env.USERPROFILE || '', '.config', 'opencode');
9
- return path.join(configDir, 'peak-hours.json');
10
- }
11
- function loadConfig() {
12
- const configPath = getConfigPath();
13
- if (fs.existsSync(configPath)) {
14
- try {
15
- const configContent = fs.readFileSync(configPath, 'utf-8');
16
- const userConfig = JSON.parse(configContent);
17
- return {
18
- enabled: userConfig.enabled !== undefined ? userConfig.enabled : DEFAULT_CONFIG.enabled
19
- };
20
- }
21
- catch (error) {
22
- console.error('Error loading peak-hours config:', error);
23
- }
24
- }
25
- return DEFAULT_CONFIG;
26
- }
27
- function renderCommandHeading(title) {
28
- return `${title}\n${'='.repeat(title.length)}`;
29
- }
30
- function renderStatusReport(status, config) {
31
- const currentTime = new Date().toISOString();
32
- const lines = [
33
- renderCommandHeading('Peak Hours Status'),
34
- '',
35
- 'Configuration:',
36
- `- enabled: ${config.enabled}`,
37
- '',
38
- 'Current Status:',
39
- `- current_time: ${currentTime}`,
40
- `- in_peak_hours: ${status.inPeakHours}`,
41
- `- transition: ${status.transitionType}`,
42
- `- time_until_${status.transitionType}: ${status.timeUntilTransition}`,
43
- '',
44
- 'Peak Hours (UTC+8):',
45
- `- start: 14:00`,
46
- `- end: 18:00`
47
- ];
48
- return lines.join('\n');
49
- }
50
- export const PeakHoursPlugin = async ({ client }) => {
51
- const config = loadConfig();
52
- const typedClient = client;
53
- return {
54
- 'command.execute.before': async (input, output) => {
55
- const command = input.command;
56
- if (!config.enabled) {
57
- output.parts = [{ type: 'text', text: 'Peak Hours plugin is disabled', ignored: true }];
58
- return;
59
- }
60
- if (command === 'peak_hours') {
61
- const status = getPeakHoursStatus();
62
- const message = formatPeakHoursMessage(status);
63
- output.parts = [{ type: 'text', text: message, ignored: true }];
64
- }
65
- else if (command === 'peak_hours_status') {
66
- const status = getPeakHoursStatus();
67
- const report = renderStatusReport(status, config);
68
- output.parts = [{ type: 'text', text: report, ignored: true }];
69
- }
70
- },
71
- 'session.created': async (_input) => {
72
- if (!config.enabled) {
73
- return;
74
- }
75
- const status = getPeakHoursStatus();
76
- const message = formatPeakHoursMessage(status);
77
- try {
78
- await typedClient.tui.showToast({
79
- body: {
80
- message,
81
- variant: status.inPeakHours ? 'warning' : 'info'
82
- }
83
- });
84
- }
85
- catch (err) {
86
- console.error('Failed to show toast:', err);
87
- }
88
- }
89
- };
90
- };