@mdrv/opencode-quota 262.0.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.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -0
  3. package/bin/copilot-quota.ts +374 -0
  4. package/bin/glm-quota.ts +467 -0
  5. package/bin/install.js +439 -0
  6. package/bin/kimi-quota.ts +314 -0
  7. package/dist/bin/copilot-quota.d.ts +8 -0
  8. package/dist/bin/copilot-quota.d.ts.map +1 -0
  9. package/dist/bin/copilot-quota.js +298 -0
  10. package/dist/bin/copilot-quota.js.map +1 -0
  11. package/dist/bin/glm-quota.d.ts +8 -0
  12. package/dist/bin/glm-quota.d.ts.map +1 -0
  13. package/dist/bin/glm-quota.js +367 -0
  14. package/dist/bin/glm-quota.js.map +1 -0
  15. package/dist/bin/kimi-quota.d.ts +3 -0
  16. package/dist/bin/kimi-quota.d.ts.map +1 -0
  17. package/dist/bin/kimi-quota.js +241 -0
  18. package/dist/bin/kimi-quota.js.map +1 -0
  19. package/dist/src/api/client.d.ts +76 -0
  20. package/dist/src/api/client.d.ts.map +1 -0
  21. package/dist/src/api/client.js +203 -0
  22. package/dist/src/api/client.js.map +1 -0
  23. package/dist/src/api/endpoints.d.ts +22 -0
  24. package/dist/src/api/endpoints.d.ts.map +1 -0
  25. package/dist/src/api/endpoints.js +41 -0
  26. package/dist/src/api/endpoints.js.map +1 -0
  27. package/dist/src/api/platforms.d.ts +20 -0
  28. package/dist/src/api/platforms.d.ts.map +1 -0
  29. package/dist/src/api/platforms.js +38 -0
  30. package/dist/src/api/platforms.js.map +1 -0
  31. package/dist/src/index.d.ts +10 -0
  32. package/dist/src/index.d.ts.map +1 -0
  33. package/dist/src/index.js +723 -0
  34. package/dist/src/index.js.map +1 -0
  35. package/dist/src/shared/logging.d.ts +7 -0
  36. package/dist/src/shared/logging.d.ts.map +1 -0
  37. package/dist/src/shared/logging.js +29 -0
  38. package/dist/src/shared/logging.js.map +1 -0
  39. package/dist/src/utils/box-constants.d.ts +43 -0
  40. package/dist/src/utils/box-constants.d.ts.map +1 -0
  41. package/dist/src/utils/box-constants.js +43 -0
  42. package/dist/src/utils/box-constants.js.map +1 -0
  43. package/dist/src/utils/date-formatter.d.ts +17 -0
  44. package/dist/src/utils/date-formatter.d.ts.map +1 -0
  45. package/dist/src/utils/date-formatter.js +33 -0
  46. package/dist/src/utils/date-formatter.js.map +1 -0
  47. package/dist/src/utils/error-formatter.d.ts +17 -0
  48. package/dist/src/utils/error-formatter.d.ts.map +1 -0
  49. package/dist/src/utils/error-formatter.js +60 -0
  50. package/dist/src/utils/error-formatter.js.map +1 -0
  51. package/dist/src/utils/progress-bar.d.ts +35 -0
  52. package/dist/src/utils/progress-bar.d.ts.map +1 -0
  53. package/dist/src/utils/progress-bar.js +43 -0
  54. package/dist/src/utils/progress-bar.js.map +1 -0
  55. package/dist/src/utils/reset-timer.d.ts +11 -0
  56. package/dist/src/utils/reset-timer.d.ts.map +1 -0
  57. package/dist/src/utils/reset-timer.js +32 -0
  58. package/dist/src/utils/reset-timer.js.map +1 -0
  59. package/dist/src/utils/time-window.d.ts +30 -0
  60. package/dist/src/utils/time-window.d.ts.map +1 -0
  61. package/dist/src/utils/time-window.js +34 -0
  62. package/dist/src/utils/time-window.js.map +1 -0
  63. package/dist/tests/error-handling/api-errors.test.d.ts +7 -0
  64. package/dist/tests/error-handling/api-errors.test.d.ts.map +1 -0
  65. package/dist/tests/error-handling/api-errors.test.js +110 -0
  66. package/dist/tests/error-handling/api-errors.test.js.map +1 -0
  67. package/dist/tests/error-handling/auth-errors.test.d.ts +7 -0
  68. package/dist/tests/error-handling/auth-errors.test.d.ts.map +1 -0
  69. package/dist/tests/error-handling/auth-errors.test.js +110 -0
  70. package/dist/tests/error-handling/auth-errors.test.js.map +1 -0
  71. package/dist/tests/error-handling/network-errors.test.d.ts +7 -0
  72. package/dist/tests/error-handling/network-errors.test.d.ts.map +1 -0
  73. package/dist/tests/error-handling/network-errors.test.js +94 -0
  74. package/dist/tests/error-handling/network-errors.test.js.map +1 -0
  75. package/dist/tests/error-handling/parse-errors.test.d.ts +7 -0
  76. package/dist/tests/error-handling/parse-errors.test.d.ts.map +1 -0
  77. package/dist/tests/error-handling/parse-errors.test.js +87 -0
  78. package/dist/tests/error-handling/parse-errors.test.js.map +1 -0
  79. package/dist/tests/error-handling/token-sanitization.test.d.ts +2 -0
  80. package/dist/tests/error-handling/token-sanitization.test.d.ts.map +1 -0
  81. package/dist/tests/error-handling/token-sanitization.test.js +59 -0
  82. package/dist/tests/error-handling/token-sanitization.test.js.map +1 -0
  83. package/dist/tests/functional/date-formatter.test.d.ts +5 -0
  84. package/dist/tests/functional/date-formatter.test.d.ts.map +1 -0
  85. package/dist/tests/functional/date-formatter.test.js +46 -0
  86. package/dist/tests/functional/date-formatter.test.js.map +1 -0
  87. package/dist/tests/functional/progress-bar.test.d.ts +5 -0
  88. package/dist/tests/functional/progress-bar.test.d.ts.map +1 -0
  89. package/dist/tests/functional/progress-bar.test.js +82 -0
  90. package/dist/tests/functional/progress-bar.test.js.map +1 -0
  91. package/dist/tests/functional/reset-timer.test.d.ts +6 -0
  92. package/dist/tests/functional/reset-timer.test.d.ts.map +1 -0
  93. package/dist/tests/functional/reset-timer.test.js +67 -0
  94. package/dist/tests/functional/reset-timer.test.js.map +1 -0
  95. package/dist/tests/functional/time-window.test.d.ts +5 -0
  96. package/dist/tests/functional/time-window.test.d.ts.map +1 -0
  97. package/dist/tests/functional/time-window.test.js +46 -0
  98. package/dist/tests/functional/time-window.test.js.map +1 -0
  99. package/dist/tests/integration/box-alignment.test.d.ts +8 -0
  100. package/dist/tests/integration/box-alignment.test.d.ts.map +1 -0
  101. package/dist/tests/integration/box-alignment.test.js +238 -0
  102. package/dist/tests/integration/box-alignment.test.js.map +1 -0
  103. package/dist/tests/integration/error-handling.test.d.ts +2 -0
  104. package/dist/tests/integration/error-handling.test.d.ts.map +1 -0
  105. package/dist/tests/integration/error-handling.test.js +36 -0
  106. package/dist/tests/integration/error-handling.test.js.map +1 -0
  107. package/dist/tests/integration/installer-config.test.d.ts +2 -0
  108. package/dist/tests/integration/installer-config.test.d.ts.map +1 -0
  109. package/dist/tests/integration/installer-config.test.js +65 -0
  110. package/dist/tests/integration/installer-config.test.js.map +1 -0
  111. package/dist/tests/integration/plugin-catch-block.test.d.ts +2 -0
  112. package/dist/tests/integration/plugin-catch-block.test.d.ts.map +1 -0
  113. package/dist/tests/integration/plugin-catch-block.test.js +134 -0
  114. package/dist/tests/integration/plugin-catch-block.test.js.map +1 -0
  115. package/dist/tests/integration/reset-time-display.test.d.ts +6 -0
  116. package/dist/tests/integration/reset-time-display.test.d.ts.map +1 -0
  117. package/dist/tests/integration/reset-time-display.test.js +138 -0
  118. package/dist/tests/integration/reset-time-display.test.js.map +1 -0
  119. package/dist/tests/module/http-client.test.d.ts +2 -0
  120. package/dist/tests/module/http-client.test.d.ts.map +1 -0
  121. package/dist/tests/module/http-client.test.js +49 -0
  122. package/dist/tests/module/http-client.test.js.map +1 -0
  123. package/dist/tests/module/platform-detection.test.d.ts +5 -0
  124. package/dist/tests/module/platform-detection.test.d.ts.map +1 -0
  125. package/dist/tests/module/platform-detection.test.js +48 -0
  126. package/dist/tests/module/platform-detection.test.js.map +1 -0
  127. package/integration/agents/copilot-quota-exec.md +20 -0
  128. package/integration/agents/glm-quota-exec.md +20 -0
  129. package/integration/command/copilot_quota.md +6 -0
  130. package/integration/command/glm_quota.md +6 -0
  131. package/integration/skills/copilot-quota/SKILL.md +11 -0
  132. package/integration/skills/glm-quota/SKILL.md +11 -0
  133. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer-config.test.js","sourceRoot":"","sources":["../../../tests/integration/installer-config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-catch-block.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-catch-block.test.d.ts","sourceRoot":"","sources":["../../../tests/integration/plugin-catch-block.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ import * as assert from 'node:assert';
2
+ import { describe, test } from 'node:test';
3
+ import { GlmQuotaPlugin } from '../../src/index.js';
4
+ import { BOX_WIDTH } from '../../src/utils/box-constants.js';
5
+ describe('Integration: Plugin Error Catch Block', () => {
6
+ describe('Global Error Catch Behavior', () => {
7
+ test('should box generic Error objects', async () => {
8
+ // Set up credentials to bypass credential check
9
+ process.env.ZAI_API_KEY = 'test-token';
10
+ try {
11
+ // Create plugin instance
12
+ const plugin = await GlmQuotaPlugin({});
13
+ const tool = plugin.tool.glm_quota;
14
+ // Mock Date constructor to throw an error
15
+ const originalDate = global.Date;
16
+ try {
17
+ class ThrowingDate extends Date {
18
+ constructor() {
19
+ super();
20
+ throw new Error('Date constructor failed');
21
+ }
22
+ }
23
+ global.Date = ThrowingDate;
24
+ const result = await tool.execute();
25
+ // Verify boxed error format
26
+ const lines = result.split('\n');
27
+ assert.ok(result.includes('╔'), 'Output should contain top border');
28
+ assert.ok(result.includes('╚'), 'Output should contain bottom border');
29
+ assert.ok(result.includes('Date constructor failed'), 'Error message should be present');
30
+ assert.strictEqual(lines[0].length, BOX_WIDTH.TOTAL, 'Box width should match');
31
+ }
32
+ finally {
33
+ global.Date = originalDate;
34
+ }
35
+ }
36
+ finally {
37
+ delete process.env.ZAI_API_KEY;
38
+ }
39
+ });
40
+ test('should box string errors', async () => {
41
+ process.env.ZAI_API_KEY = 'test-token';
42
+ try {
43
+ const plugin = await GlmQuotaPlugin({});
44
+ const tool = plugin.tool.glm_quota;
45
+ const originalDate = global.Date;
46
+ try {
47
+ // Throw a string instead of Error
48
+ class ThrowingDate extends Date {
49
+ constructor() {
50
+ super();
51
+ throw 'String error message';
52
+ }
53
+ }
54
+ global.Date = ThrowingDate;
55
+ const result = await tool.execute();
56
+ const lines = result.split('\n');
57
+ assert.ok(result.includes('╔'), 'Output should contain top border');
58
+ assert.ok(result.includes('╚'), 'Output should contain bottom border');
59
+ assert.ok(result.includes('String error message'), 'String error should be boxed');
60
+ assert.strictEqual(lines[0].length, BOX_WIDTH.TOTAL, 'Box width should match');
61
+ }
62
+ finally {
63
+ global.Date = originalDate;
64
+ }
65
+ }
66
+ finally {
67
+ delete process.env.ZAI_API_KEY;
68
+ }
69
+ });
70
+ test('should handle error with newlines', async () => {
71
+ process.env.ZAI_API_KEY = 'test-token';
72
+ try {
73
+ const plugin = await GlmQuotaPlugin({});
74
+ const tool = plugin.tool.glm_quota;
75
+ const originalDate = global.Date;
76
+ try {
77
+ // Throw error with multiline message
78
+ class ThrowingDate extends Date {
79
+ constructor() {
80
+ super();
81
+ throw new Error('Line 1 error\nLine 2 error\nLine 3 error');
82
+ }
83
+ }
84
+ global.Date = ThrowingDate;
85
+ const result = await tool.execute();
86
+ const lines = result.split('\n');
87
+ assert.ok(result.includes('╔'), 'Output should contain top border');
88
+ assert.ok(result.includes('╚'), 'Output should contain bottom border');
89
+ assert.ok(result.includes('Line 1 error'), 'First line should be present');
90
+ assert.strictEqual(lines[0].length, BOX_WIDTH.TOTAL, 'Box width should match');
91
+ }
92
+ finally {
93
+ global.Date = originalDate;
94
+ }
95
+ }
96
+ finally {
97
+ delete process.env.ZAI_API_KEY;
98
+ }
99
+ });
100
+ });
101
+ describe('Box Width Consistency', () => {
102
+ test('should maintain 60-character box width for all errors', async () => {
103
+ process.env.ZAI_API_KEY = 'test-token';
104
+ try {
105
+ const plugin = await GlmQuotaPlugin({});
106
+ const tool = plugin.tool.glm_quota;
107
+ const originalDate = global.Date;
108
+ try {
109
+ class ThrowingDate extends Date {
110
+ constructor() {
111
+ super();
112
+ throw new Error('Test error message');
113
+ }
114
+ }
115
+ global.Date = ThrowingDate;
116
+ const result = await tool.execute();
117
+ const lines = result.split('\n');
118
+ // Check that all border lines have correct width
119
+ const borderLines = lines.filter(line => line.startsWith('╔') || line.startsWith('╚') || line.startsWith('║'));
120
+ for (const borderLine of borderLines) {
121
+ assert.strictEqual(borderLine.length, BOX_WIDTH.TOTAL, `Border line should be ${BOX_WIDTH.TOTAL} chars: "${borderLine}"`);
122
+ }
123
+ }
124
+ finally {
125
+ global.Date = originalDate;
126
+ }
127
+ }
128
+ finally {
129
+ delete process.env.ZAI_API_KEY;
130
+ }
131
+ });
132
+ });
133
+ });
134
+ //# sourceMappingURL=plugin-catch-block.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-catch-block.test.js","sourceRoot":"","sources":["../../../tests/integration/plugin-catch-block.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAO5D,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACtD,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC5C,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YACnD,gDAAgD;YAChD,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAA;YAEtC,IAAI,CAAC;gBACJ,yBAAyB;gBACzB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAA8B,CAAC,CAAA;gBACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAK,CAAC,SAAS,CAAA;gBAEnC,0CAA0C;gBAC1C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAA;gBAEhC,IAAI,CAAC;oBACJ,MAAM,YAAa,SAAQ,IAAI;wBAC9B;4BACC,KAAK,EAAE,CAAA;4BACP,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;wBAC3C,CAAC;qBACD;oBAED,MAAM,CAAC,IAAI,GAAG,YAA0C,CAAA;oBAExD,MAAM,MAAM,GAAG,MAAO,IAAgC,CAAC,OAAO,EAAE,CAAA;oBAEhE,4BAA4B;oBAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAChC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,kCAAkC,CAAC,CAAA;oBACnE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,qCAAqC,CAAC,CAAA;oBACtE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,iCAAiC,CAAC,CAAA;oBACxF,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC/E,CAAC;wBAAS,CAAC;oBACV,MAAM,CAAC,IAAI,GAAG,YAAY,CAAA;gBAC3B,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YAC/B,CAAC;QACF,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YAC3C,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAA;YAEtC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAA8B,CAAC,CAAA;gBACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAK,CAAC,SAAS,CAAA;gBAEnC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAA;gBAEhC,IAAI,CAAC;oBACJ,kCAAkC;oBAClC,MAAM,YAAa,SAAQ,IAAI;wBAC9B;4BACC,KAAK,EAAE,CAAA;4BACP,MAAM,sBAAsB,CAAA;wBAC7B,CAAC;qBACD;oBAED,MAAM,CAAC,IAAI,GAAG,YAA0C,CAAA;oBAExD,MAAM,MAAM,GAAG,MAAO,IAAgC,CAAC,OAAO,EAAE,CAAA;oBAEhE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAChC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,kCAAkC,CAAC,CAAA;oBACnE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,qCAAqC,CAAC,CAAA;oBACtE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,8BAA8B,CAAC,CAAA;oBAClF,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC/E,CAAC;wBAAS,CAAC;oBACV,MAAM,CAAC,IAAI,GAAG,YAAY,CAAA;gBAC3B,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YAC/B,CAAC;QACF,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACpD,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAA;YAEtC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAA8B,CAAC,CAAA;gBACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAK,CAAC,SAAS,CAAA;gBAEnC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAA;gBAEhC,IAAI,CAAC;oBACJ,qCAAqC;oBACrC,MAAM,YAAa,SAAQ,IAAI;wBAC9B;4BACC,KAAK,EAAE,CAAA;4BACP,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;wBAC5D,CAAC;qBACD;oBAED,MAAM,CAAC,IAAI,GAAG,YAA0C,CAAA;oBAExD,MAAM,MAAM,GAAG,MAAO,IAAgC,CAAC,OAAO,EAAE,CAAA;oBAEhE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAChC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,kCAAkC,CAAC,CAAA;oBACnE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,qCAAqC,CAAC,CAAA;oBACtE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,8BAA8B,CAAC,CAAA;oBAC1E,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC/E,CAAC;wBAAS,CAAC;oBACV,MAAM,CAAC,IAAI,GAAG,YAAY,CAAA;gBAC3B,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YAC/B,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACtC,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACxE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAA;YAEtC,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAA8B,CAAC,CAAA;gBACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAK,CAAC,SAAS,CAAA;gBAEnC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAA;gBAEhC,IAAI,CAAC;oBACJ,MAAM,YAAa,SAAQ,IAAI;wBAC9B;4BACC,KAAK,EAAE,CAAA;4BACP,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;wBACtC,CAAC;qBACD;oBAED,MAAM,CAAC,IAAI,GAAG,YAA0C,CAAA;oBAExD,MAAM,MAAM,GAAG,MAAO,IAAgC,CAAC,OAAO,EAAE,CAAA;oBAEhE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAEhC,iDAAiD;oBACjD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAC/B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAC5E,CAAA;oBAED,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;wBACtC,MAAM,CAAC,WAAW,CACjB,UAAU,CAAC,MAAM,EACjB,SAAS,CAAC,KAAK,EACf,yBAAyB,SAAS,CAAC,KAAK,YAAY,UAAU,GAAG,CACjE,CAAA;oBACF,CAAC;gBACF,CAAC;wBAAS,CAAC;oBACV,MAAM,CAAC,IAAI,GAAG,YAAY,CAAA;gBAC3B,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;YAC/B,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Integration tests for reset time display
3
+ * Test reset countdown functionality in output formatting
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=reset-time-display.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-time-display.test.d.ts","sourceRoot":"","sources":["../../../tests/integration/reset-time-display.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Integration tests for reset time display
3
+ * Test reset countdown functionality in output formatting
4
+ */
5
+ import assert from 'node:assert';
6
+ import { describe, test } from 'node:test';
7
+ /**
8
+ * Simulate processQuotaLimit function behavior with nextResetTime
9
+ */
10
+ function mockProcessQuotaLimitWithReset(data) {
11
+ const result = { ...data };
12
+ if (result.limits && Array.isArray(result.limits)) {
13
+ result.limits = result.limits.map((item) => {
14
+ if (typeof item === 'object' && item !== null) {
15
+ const limit = item;
16
+ if (limit.type === 'TOKENS_LIMIT') {
17
+ return {
18
+ type: 'Token usage(5 Hour)',
19
+ percentage: typeof limit.percentage === 'number' ? limit.percentage : 0,
20
+ nextResetTime: limit.nextResetTime,
21
+ };
22
+ }
23
+ if (limit.type === 'TIME_LIMIT') {
24
+ return {
25
+ type: 'MCP usage(1 Month)',
26
+ percentage: typeof limit.percentage === 'number' ? limit.percentage : 0,
27
+ currentValue: limit.currentValue,
28
+ total: limit.usage,
29
+ usageDetails: limit.usageDetails,
30
+ };
31
+ }
32
+ }
33
+ return item;
34
+ });
35
+ }
36
+ return result;
37
+ }
38
+ describe('Reset Time Display Integration', () => {
39
+ /**
40
+ * Test: Quota limit processing preserves nextResetTime
41
+ */
42
+ test('preserves nextResetTime in processed quota data', () => {
43
+ const resetTime = Date.now() + (4 * 60 * 60 * 1000); // 4 hours from now
44
+ const apiResponse = {
45
+ limits: [
46
+ {
47
+ type: 'TOKENS_LIMIT',
48
+ percentage: 45,
49
+ unit: 3,
50
+ number: 5,
51
+ nextResetTime: resetTime,
52
+ },
53
+ ],
54
+ };
55
+ const processed = mockProcessQuotaLimitWithReset(apiResponse);
56
+ const limits = processed.limits;
57
+ assert.ok(limits, 'Should have limits array');
58
+ assert.strictEqual(limits.length, 1, 'Should have 1 limit');
59
+ assert.strictEqual(limits[0].nextResetTime, resetTime, 'Should preserve nextResetTime');
60
+ });
61
+ /**
62
+ * Test: Quota limit processing handles missing nextResetTime
63
+ */
64
+ test('handles missing nextResetTime gracefully', () => {
65
+ const apiResponse = {
66
+ limits: [
67
+ {
68
+ type: 'TOKENS_LIMIT',
69
+ percentage: 45,
70
+ unit: 3,
71
+ number: 5,
72
+ // NO nextResetTime field
73
+ },
74
+ ],
75
+ };
76
+ const processed = mockProcessQuotaLimitWithReset(apiResponse);
77
+ const limits = processed.limits;
78
+ assert.ok(limits, 'Should have limits array');
79
+ assert.strictEqual(limits.length, 1, 'Should have 1 limit');
80
+ assert.strictEqual(limits[0].nextResetTime, undefined, 'nextResetTime should be undefined when not provided');
81
+ });
82
+ /**
83
+ * Test: Reset countdown calculation works with processed data
84
+ */
85
+ test('reset countdown works with processed quota data', () => {
86
+ const resetTime = Date.now() + (2 * 60 * 60 * 1000) + (30 * 60 * 1000); // 2h 30m from now
87
+ const apiResponse = {
88
+ limits: [
89
+ {
90
+ type: 'TOKENS_LIMIT',
91
+ percentage: 75,
92
+ unit: 3,
93
+ number: 5,
94
+ nextResetTime: resetTime,
95
+ },
96
+ ],
97
+ };
98
+ const processed = mockProcessQuotaLimitWithReset(apiResponse);
99
+ const limit = (processed.limits?.[0] ?? {});
100
+ assert.ok(limit, 'Should have limit data');
101
+ assert.strictEqual(limit.type, 'Token usage(5 Hour)', 'Should have correct type');
102
+ assert.strictEqual(limit.percentage, 75, 'Should preserve percentage');
103
+ assert.strictEqual(limit.nextResetTime, resetTime, 'Should preserve reset time');
104
+ });
105
+ /**
106
+ * Test: Multiple limits with mixed reset time availability
107
+ */
108
+ test('handles multiple limits with different reset time availability', () => {
109
+ const resetTime = Date.now() + (3 * 60 * 60 * 1000); // 3 hours from now
110
+ const apiResponse = {
111
+ limits: [
112
+ {
113
+ type: 'TOKENS_LIMIT',
114
+ percentage: 60,
115
+ unit: 3,
116
+ number: 5,
117
+ nextResetTime: resetTime,
118
+ },
119
+ {
120
+ type: 'TIME_LIMIT',
121
+ percentage: 85,
122
+ currentValue: 85,
123
+ usage: 100,
124
+ // NO nextResetTime for TIME_LIMIT
125
+ },
126
+ ],
127
+ };
128
+ const processed = mockProcessQuotaLimitWithReset(apiResponse);
129
+ const limits = processed.limits;
130
+ assert.ok(limits, 'Should have limits array');
131
+ assert.strictEqual(limits.length, 2, 'Should have 2 limits');
132
+ const tokenLimit = limits[0];
133
+ const timeLimit = limits[1];
134
+ assert.strictEqual(tokenLimit.nextResetTime, resetTime, 'Token limit should have reset time');
135
+ assert.strictEqual(timeLimit.nextResetTime, undefined, 'Time limit should not have reset time');
136
+ });
137
+ });
138
+ //# sourceMappingURL=reset-time-display.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-time-display.test.js","sourceRoot":"","sources":["../../../tests/integration/reset-time-display.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http-client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.test.d.ts","sourceRoot":"","sources":["../../../tests/module/http-client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import * as assert from 'node:assert';
2
+ import { readFileSync } from 'node:fs';
3
+ import * as https from 'node:https';
4
+ import { describe, test } from 'node:test';
5
+ import { makeRequest } from '../../src/api/client.js';
6
+ describe('makeRequest', () => {
7
+ test('sends auth header and parses JSON response', async () => {
8
+ const authToken = 'test-token';
9
+ const url = 'https://api.z.ai/api/monitor/usage/quota/limit';
10
+ const responseBody = { limits: [] };
11
+ const key = readFileSync('tests/fixtures/test-key.pem', 'utf-8');
12
+ const cert = readFileSync('tests/fixtures/test-cert.pem', 'utf-8');
13
+ // Start a local HTTPS server with self-signed cert
14
+ const server = https.createServer({ key, cert }, (req, res) => {
15
+ // Assert auth header is present
16
+ assert.ok(req.headers.authorization, 'Should have Authorization header');
17
+ assert.strictEqual(req.headers.authorization, authToken, 'Auth header should match token');
18
+ res.writeHead(200, { 'Content-Type': 'application/json' });
19
+ res.end(JSON.stringify(responseBody));
20
+ });
21
+ let serverPort = 0; // Initialize to 0 to avoid "used before assigned" error
22
+ await new Promise((resolve) => {
23
+ server.listen(0, 'localhost', () => {
24
+ const address = server.address();
25
+ if (address) {
26
+ serverPort = address.port;
27
+ }
28
+ resolve();
29
+ });
30
+ });
31
+ // Wait for server to be fully ready (increased from 50ms to avoid ECONNREFUSED)
32
+ await new Promise(resolve => setTimeout(resolve, 200));
33
+ // Temporarily trust the test certificate for this process
34
+ const originalCa = https.globalAgent.options.ca;
35
+ https.globalAgent.options.ca = cert;
36
+ try {
37
+ const result = await makeRequest({
38
+ url: `https://localhost:${serverPort}/api/monitor/usage/quota/limit`,
39
+ authToken,
40
+ });
41
+ assert.deepStrictEqual(result, responseBody);
42
+ }
43
+ finally {
44
+ https.globalAgent.options.ca = originalCa;
45
+ await new Promise((resolve) => server.close(() => resolve()));
46
+ }
47
+ });
48
+ });
49
+ //# sourceMappingURL=http-client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.test.js","sourceRoot":"","sources":["../../../tests/module/http-client.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAQ,IAAI,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC5B,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,SAAS,GAAG,YAAY,CAAA;QAC9B,MAAM,GAAG,GAAG,gDAAgD,CAAA;QAC5D,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QAEnC,MAAM,GAAG,GAAG,YAAY,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAA;QAChE,MAAM,IAAI,GAAG,YAAY,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAA;QAElE,mDAAmD;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC7D,gCAAgC;YAChC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAA;YACxE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,EAAE,gCAAgC,CAAC,CAAA;YAE1F,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;QAEF,IAAI,UAAU,GAAG,CAAC,CAAA,CAAC,wDAAwD;QAC3E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;gBAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAsB,CAAA;gBACpD,IAAI,OAAO,EAAE,CAAC;oBACb,UAAU,GAAG,OAAO,CAAC,IAAI,CAAA;gBAC1B,CAAC;gBACD,OAAO,EAAE,CAAA;YACV,CAAC,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,gFAAgF;QAChF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QAEtD,0DAA0D;QAC1D,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAA;QAC/C,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAA;QAEnC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;gBAChC,GAAG,EAAE,qBAAqB,UAAU,gCAAgC;gBACpE,SAAS;aACT,CAAC,CAAA;YAEF,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QAC7C,CAAC;gBAAS,CAAC;YACV,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAA;YACzC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACpE,CAAC;IACF,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Module tests for platform detection
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=platform-detection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-detection.test.d.ts","sourceRoot":"","sources":["../../../tests/module/platform-detection.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Module tests for platform detection
3
+ */
4
+ import assert from 'node:assert';
5
+ import { describe, test } from 'node:test';
6
+ import { detectPlatform, getPlatformName } from '../../src/api/platforms.js';
7
+ describe('detectPlatform', () => {
8
+ test('detects ZAI from zai-coding-plan', () => {
9
+ assert.strictEqual(detectPlatform('zai-coding-plan'), 'ZAI');
10
+ });
11
+ test('detects ZAI from zai', () => {
12
+ assert.strictEqual(detectPlatform('zai'), 'ZAI');
13
+ });
14
+ test('detects ZAI from z-ai', () => {
15
+ assert.strictEqual(detectPlatform('z-ai'), 'ZAI');
16
+ });
17
+ test('detects ZAI from z.ai', () => {
18
+ assert.strictEqual(detectPlatform('z.ai'), 'ZAI');
19
+ });
20
+ test('detects ZHIPU from zhipu', () => {
21
+ assert.strictEqual(detectPlatform('zhipu'), 'ZHIPU');
22
+ });
23
+ test('detects ZHIPU from zhipuai', () => {
24
+ assert.strictEqual(detectPlatform('zhipuai'), 'ZHIPU');
25
+ });
26
+ test('detects ZHIPU from bigmodel', () => {
27
+ assert.strictEqual(detectPlatform('bigmodel'), 'ZHIPU');
28
+ });
29
+ test('detects ZHIPU from dev.bigmodel.cn', () => {
30
+ assert.strictEqual(detectPlatform('dev.bigmodel.cn'), 'ZHIPU');
31
+ });
32
+ test('returns null for unknown provider', () => {
33
+ assert.strictEqual(detectPlatform('unknown'), null);
34
+ });
35
+ test('is case insensitive', () => {
36
+ assert.strictEqual(detectPlatform('ZAI'), 'ZAI');
37
+ assert.strictEqual(detectPlatform('Zhipu'), 'ZHIPU');
38
+ });
39
+ });
40
+ describe('getPlatformName', () => {
41
+ test('returns Z.AI for ZAI platform', () => {
42
+ assert.strictEqual(getPlatformName('ZAI'), 'Z.AI');
43
+ });
44
+ test('returns ZHIPU for ZHIPU platform', () => {
45
+ assert.strictEqual(getPlatformName('ZHIPU'), 'ZHIPU');
46
+ });
47
+ });
48
+ //# sourceMappingURL=platform-detection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-detection.test.js","sourceRoot":"","sources":["../../../tests/module/platform-detection.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAiB,MAAM,4BAA4B,CAAA;AAE3F,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC/B,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;QAChD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAChC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Minimal executor for Copilot quota tool
3
+ mode: subagent
4
+ hidden: true
5
+ permission:
6
+ edit: deny
7
+ bash: deny
8
+ ---
9
+
10
+ CRITICAL INSTRUCTION: When copilot_quota tool returns output, you MUST return it EXACTLY as received, character-for-character, with NO modifications.
11
+
12
+ - Do NOT add introductory text
13
+ - Do NOT summarize
14
+ - Do NOT reformat
15
+ - Do NOT explain anything
16
+ - Do NOT add any commentary
17
+ - Return ONLY the raw string from the tool
18
+
19
+ Example of WRONG behavior: 'Here is your usage: [summary]'
20
+ Example of CORRECT behavior: [paste entire tool output verbatim]
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Minimal executor for GLM quota tool
3
+ mode: subagent
4
+ hidden: true
5
+ permission:
6
+ edit: deny
7
+ bash: deny
8
+ ---
9
+
10
+ CRITICAL INSTRUCTION: When the glm_quota tool returns output, you MUST return it EXACTLY as received, character-for-character, with NO modifications.
11
+
12
+ - Do NOT add introductory text
13
+ - Do NOT summarize
14
+ - Do NOT reformat
15
+ - Do NOT explain anything
16
+ - Do NOT add any commentary
17
+ - Return ONLY the raw string from the tool
18
+
19
+ Example of WRONG behavior: 'Here is your usage: [summary]'
20
+ Example of CORRECT behavior: [paste entire tool output verbatim]
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Execute GitHub Copilot quota check
3
+ agent: copilot-quota-exec
4
+ ---
5
+
6
+ Execute copilot_quota tool and return its output EXACTLY as received without any modification or summarization.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Execute GLM quota check
3
+ agent: glm-quota-exec
4
+ ---
5
+
6
+ Execute glm_quota tool and return its output EXACTLY as received without any modification or summarization.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: copilot-quota
3
+ description: Query GitHub Copilot Pro usage statistics including monthly requests, costs, and model usage
4
+ parameters:
5
+ - name: detailed
6
+ type: boolean
7
+ optional: true
8
+ description: Show detailed usage breakdown by model
9
+ ---
10
+
11
+ Query GitHub Copilot Pro quota usage including monthly requests and costs.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: glm-quota
3
+ description: Query Z.ai GLM Coding Plan usage statistics including quota limits, model usage, and MCP tool usage
4
+ parameters:
5
+ - name: detailed
6
+ type: boolean
7
+ optional: true
8
+ description: Show detailed usage breakdown
9
+ ---
10
+
11
+ Query GLM quota usage including token limits and MCP tool usage.
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@mdrv/opencode-quota",
3
+ "version": "v262.0.0",
4
+ "type": "module",
5
+ "description": "OpenCode plugin for querying Z.AI GLM Coding Plan and GitHub Copilot usage statistics",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "glm-quota": "./bin/glm-quota.js",
10
+ "copilot-quota": "./bin/copilot-quota.js",
11
+ "kimi-quota": "./bin/kimi-quota.js"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "integration",
16
+ "bin",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "fmt": "dprint fmt",
23
+ "fmt:check": "dprint check",
24
+ "test": "bun test",
25
+ "prepublishOnly": "dprint fmt && bun run build && bun run test",
26
+ "install:opencode": "node bin/install.js"
27
+ },
28
+ "keywords": [
29
+ "opencode",
30
+ "opencode-plugin",
31
+ "zai",
32
+ "z.ai",
33
+ "zhipu",
34
+ "glm",
35
+ "quota",
36
+ "usage",
37
+ "coding-plan",
38
+ "ai",
39
+ "llm",
40
+ "github",
41
+ "copilot"
42
+ ],
43
+ "author": "Umar Alfarouk",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/mdrv/opencode-quota.git"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/mdrv/opencode-quota/issues"
51
+ },
52
+ "homepage": "https://github.com/mdrv/opencode-quota#readme",
53
+ "dependencies": {
54
+ "@logtape/logtape": "^0.9.0",
55
+ "jsonc-parser": "^3.2.0"
56
+ },
57
+ "peerDependencies": {
58
+ "@opencode-ai/plugin": ">=0.1.0"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "devDependencies": {
64
+ "@opencode-ai/plugin": "^1.1.30",
65
+ "@types/node": "^20.0.0",
66
+ "bun-types": "^1.0.0",
67
+ "typescript": "^5.0.0"
68
+ }
69
+ }