@meet-ai/cli 0.0.18 → 0.0.19
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/dist/index.js +1359 -42
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -519,7 +519,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
519
519
|
});
|
|
520
520
|
|
|
521
521
|
// src/lib/output.ts
|
|
522
|
-
var import_picocolors, ok = (msg) => console.log(import_picocolors.default.green(msg)), err = (msg) => console.error(import_picocolors.default.red(`error: ${msg}`));
|
|
522
|
+
var import_picocolors, ok = (msg) => console.log(import_picocolors.default.green(msg)), err = (msg) => console.error(import_picocolors.default.red(`error: ${msg}`)), info = (msg) => console.log(import_picocolors.default.cyan(msg));
|
|
523
523
|
var init_output = __esm(() => {
|
|
524
524
|
import_picocolors = __toESM(require_picocolors(), 1);
|
|
525
525
|
});
|
|
@@ -15703,10 +15703,10 @@ var init_command10 = __esm(() => {
|
|
|
15703
15703
|
// ../../node_modules/.bun/react@19.2.4/node_modules/react/cjs/react.development.js
|
|
15704
15704
|
var require_react_development = __commonJS((exports, module) => {
|
|
15705
15705
|
(function() {
|
|
15706
|
-
function defineDeprecationWarning(methodName,
|
|
15706
|
+
function defineDeprecationWarning(methodName, info2) {
|
|
15707
15707
|
Object.defineProperty(Component.prototype, methodName, {
|
|
15708
15708
|
get: function() {
|
|
15709
|
-
console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",
|
|
15709
|
+
console.warn("%s(...) is deprecated in plain JavaScript React classes. %s", info2[0], info2[1]);
|
|
15710
15710
|
}
|
|
15711
15711
|
});
|
|
15712
15712
|
}
|
|
@@ -20755,15 +20755,15 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
20755
20755
|
}
|
|
20756
20756
|
function getStackByFiberInDevAndProd(workInProgress2) {
|
|
20757
20757
|
try {
|
|
20758
|
-
var
|
|
20758
|
+
var info2 = "", previous = null;
|
|
20759
20759
|
do {
|
|
20760
|
-
|
|
20760
|
+
info2 += describeFiber(workInProgress2, previous);
|
|
20761
20761
|
var debugInfo = workInProgress2._debugInfo;
|
|
20762
20762
|
if (debugInfo)
|
|
20763
20763
|
for (var i = debugInfo.length - 1;0 <= i; i--) {
|
|
20764
20764
|
var entry = debugInfo[i];
|
|
20765
20765
|
if (typeof entry.name === "string") {
|
|
20766
|
-
var JSCompiler_temp_const =
|
|
20766
|
+
var JSCompiler_temp_const = info2;
|
|
20767
20767
|
a: {
|
|
20768
20768
|
var { name, env: env2, debugLocation: location } = entry;
|
|
20769
20769
|
if (location != null) {
|
|
@@ -20777,13 +20777,13 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
|
|
|
20777
20777
|
}
|
|
20778
20778
|
JSCompiler_inline_result = describeBuiltInComponentFrame(name + (env2 ? " [" + env2 + "]" : ""));
|
|
20779
20779
|
}
|
|
20780
|
-
|
|
20780
|
+
info2 = JSCompiler_temp_const + JSCompiler_inline_result;
|
|
20781
20781
|
}
|
|
20782
20782
|
}
|
|
20783
20783
|
previous = workInProgress2;
|
|
20784
20784
|
workInProgress2 = workInProgress2.return;
|
|
20785
20785
|
} while (workInProgress2);
|
|
20786
|
-
return
|
|
20786
|
+
return info2;
|
|
20787
20787
|
} catch (x) {
|
|
20788
20788
|
return `
|
|
20789
20789
|
Error generating stack: ` + x.message + `
|
|
@@ -21151,31 +21151,31 @@ Error generating stack: ` + x.message + `
|
|
|
21151
21151
|
return "";
|
|
21152
21152
|
var workInProgress2 = current;
|
|
21153
21153
|
try {
|
|
21154
|
-
var
|
|
21154
|
+
var info2 = "";
|
|
21155
21155
|
workInProgress2.tag === 6 && (workInProgress2 = workInProgress2.return);
|
|
21156
21156
|
switch (workInProgress2.tag) {
|
|
21157
21157
|
case 26:
|
|
21158
21158
|
case 27:
|
|
21159
21159
|
case 5:
|
|
21160
|
-
|
|
21160
|
+
info2 += describeBuiltInComponentFrame(workInProgress2.type);
|
|
21161
21161
|
break;
|
|
21162
21162
|
case 13:
|
|
21163
|
-
|
|
21163
|
+
info2 += describeBuiltInComponentFrame("Suspense");
|
|
21164
21164
|
break;
|
|
21165
21165
|
case 19:
|
|
21166
|
-
|
|
21166
|
+
info2 += describeBuiltInComponentFrame("SuspenseList");
|
|
21167
21167
|
break;
|
|
21168
21168
|
case 31:
|
|
21169
|
-
|
|
21169
|
+
info2 += describeBuiltInComponentFrame("Activity");
|
|
21170
21170
|
break;
|
|
21171
21171
|
case 30:
|
|
21172
21172
|
case 0:
|
|
21173
21173
|
case 15:
|
|
21174
21174
|
case 1:
|
|
21175
|
-
workInProgress2._debugOwner ||
|
|
21175
|
+
workInProgress2._debugOwner || info2 !== "" || (info2 += describeFunctionComponentFrameWithoutLineNumber(workInProgress2.type));
|
|
21176
21176
|
break;
|
|
21177
21177
|
case 11:
|
|
21178
|
-
workInProgress2._debugOwner ||
|
|
21178
|
+
workInProgress2._debugOwner || info2 !== "" || (info2 += describeFunctionComponentFrameWithoutLineNumber(workInProgress2.type.render));
|
|
21179
21179
|
}
|
|
21180
21180
|
for (;workInProgress2; )
|
|
21181
21181
|
if (typeof workInProgress2.tag === "number") {
|
|
@@ -21184,16 +21184,16 @@ Error generating stack: ` + x.message + `
|
|
|
21184
21184
|
var debugStack = fiber._debugStack;
|
|
21185
21185
|
if (workInProgress2 && debugStack) {
|
|
21186
21186
|
var formattedStack = formatOwnerStack(debugStack);
|
|
21187
|
-
formattedStack !== "" && (
|
|
21187
|
+
formattedStack !== "" && (info2 += `
|
|
21188
21188
|
` + formattedStack);
|
|
21189
21189
|
}
|
|
21190
21190
|
} else if (workInProgress2.debugStack != null) {
|
|
21191
21191
|
var ownerStack = workInProgress2.debugStack;
|
|
21192
|
-
(workInProgress2 = workInProgress2.owner) && ownerStack && (
|
|
21192
|
+
(workInProgress2 = workInProgress2.owner) && ownerStack && (info2 += `
|
|
21193
21193
|
` + formatOwnerStack(ownerStack));
|
|
21194
21194
|
} else
|
|
21195
21195
|
break;
|
|
21196
|
-
var JSCompiler_inline_result =
|
|
21196
|
+
var JSCompiler_inline_result = info2;
|
|
21197
21197
|
} catch (x) {
|
|
21198
21198
|
JSCompiler_inline_result = `
|
|
21199
21199
|
Error generating stack: ` + x.message + `
|
|
@@ -34551,13 +34551,13 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
34551
34551
|
}
|
|
34552
34552
|
}
|
|
34553
34553
|
if (this.options.verifyClient) {
|
|
34554
|
-
const
|
|
34554
|
+
const info2 = {
|
|
34555
34555
|
origin: req.headers[`${version2 === 8 ? "sec-websocket-origin" : "origin"}`],
|
|
34556
34556
|
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
34557
34557
|
req
|
|
34558
34558
|
};
|
|
34559
34559
|
if (this.options.verifyClient.length === 2) {
|
|
34560
|
-
this.options.verifyClient(
|
|
34560
|
+
this.options.verifyClient(info2, (verified, code, message, headers) => {
|
|
34561
34561
|
if (!verified) {
|
|
34562
34562
|
return abortHandshake(socket, code || 401, message, headers);
|
|
34563
34563
|
}
|
|
@@ -34565,7 +34565,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
34565
34565
|
});
|
|
34566
34566
|
return;
|
|
34567
34567
|
}
|
|
34568
|
-
if (!this.options.verifyClient(
|
|
34568
|
+
if (!this.options.verifyClient(info2))
|
|
34569
34569
|
return abortHandshake(socket, 401);
|
|
34570
34570
|
}
|
|
34571
34571
|
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
@@ -41539,7 +41539,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41539
41539
|
}
|
|
41540
41540
|
function getOwnerStackByComponentInfoInDev(componentInfo) {
|
|
41541
41541
|
try {
|
|
41542
|
-
var
|
|
41542
|
+
var info2 = "";
|
|
41543
41543
|
if (!componentInfo.owner && typeof componentInfo.name === "string") {
|
|
41544
41544
|
return describeBuiltInComponentFrame(componentInfo.name);
|
|
41545
41545
|
}
|
|
@@ -41549,14 +41549,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41549
41549
|
if (ownerStack != null) {
|
|
41550
41550
|
owner = owner.owner;
|
|
41551
41551
|
if (owner) {
|
|
41552
|
-
|
|
41552
|
+
info2 += `
|
|
41553
41553
|
` + formatOwnerStack(ownerStack);
|
|
41554
41554
|
}
|
|
41555
41555
|
} else {
|
|
41556
41556
|
break;
|
|
41557
41557
|
}
|
|
41558
41558
|
}
|
|
41559
|
-
return
|
|
41559
|
+
return info2;
|
|
41560
41560
|
} catch (x) {
|
|
41561
41561
|
return `
|
|
41562
41562
|
Error generating stack: ` + x.message + `
|
|
@@ -41819,22 +41819,22 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41819
41819
|
}
|
|
41820
41820
|
function getStackByFiberInDevAndProd(workTagMap, workInProgress, currentDispatcherRef) {
|
|
41821
41821
|
try {
|
|
41822
|
-
var
|
|
41822
|
+
var info2 = "";
|
|
41823
41823
|
var node = workInProgress;
|
|
41824
41824
|
do {
|
|
41825
|
-
|
|
41825
|
+
info2 += describeFiber(workTagMap, node, currentDispatcherRef);
|
|
41826
41826
|
var debugInfo = node._debugInfo;
|
|
41827
41827
|
if (debugInfo) {
|
|
41828
41828
|
for (var i = debugInfo.length - 1;i >= 0; i--) {
|
|
41829
41829
|
var entry = debugInfo[i];
|
|
41830
41830
|
if (typeof entry.name === "string") {
|
|
41831
|
-
|
|
41831
|
+
info2 += describeDebugInfoFrame(entry.name, entry.env);
|
|
41832
41832
|
}
|
|
41833
41833
|
}
|
|
41834
41834
|
}
|
|
41835
41835
|
node = node.return;
|
|
41836
41836
|
} while (node);
|
|
41837
|
-
return
|
|
41837
|
+
return info2;
|
|
41838
41838
|
} catch (x) {
|
|
41839
41839
|
return `
|
|
41840
41840
|
Error generating stack: ` + x.message + `
|
|
@@ -41843,9 +41843,9 @@ Error generating stack: ` + x.message + `
|
|
|
41843
41843
|
}
|
|
41844
41844
|
function getSourceLocationByFiber(workTagMap, fiber, currentDispatcherRef) {
|
|
41845
41845
|
try {
|
|
41846
|
-
var
|
|
41847
|
-
if (
|
|
41848
|
-
return
|
|
41846
|
+
var info2 = describeFiber(workTagMap, fiber, currentDispatcherRef);
|
|
41847
|
+
if (info2 !== "") {
|
|
41848
|
+
return info2.slice(1);
|
|
41849
41849
|
}
|
|
41850
41850
|
} catch (x) {
|
|
41851
41851
|
console.error(x);
|
|
@@ -41861,7 +41861,7 @@ Error generating stack: ` + x.message + `
|
|
|
41861
41861
|
function getOwnerStackByFiberInDev(workTagMap, workInProgress, currentDispatcherRef) {
|
|
41862
41862
|
var { HostHoistable, HostSingleton, HostText, HostComponent, SuspenseComponent, SuspenseListComponent, ViewTransitionComponent, ActivityComponent } = workTagMap;
|
|
41863
41863
|
try {
|
|
41864
|
-
var
|
|
41864
|
+
var info2 = "";
|
|
41865
41865
|
if (workInProgress.tag === HostText) {
|
|
41866
41866
|
workInProgress = workInProgress.return;
|
|
41867
41867
|
}
|
|
@@ -41869,19 +41869,19 @@ Error generating stack: ` + x.message + `
|
|
|
41869
41869
|
case HostHoistable:
|
|
41870
41870
|
case HostSingleton:
|
|
41871
41871
|
case HostComponent:
|
|
41872
|
-
|
|
41872
|
+
info2 += describeBuiltInComponentFrame(workInProgress.type);
|
|
41873
41873
|
break;
|
|
41874
41874
|
case SuspenseComponent:
|
|
41875
|
-
|
|
41875
|
+
info2 += describeBuiltInComponentFrame("Suspense");
|
|
41876
41876
|
break;
|
|
41877
41877
|
case SuspenseListComponent:
|
|
41878
|
-
|
|
41878
|
+
info2 += describeBuiltInComponentFrame("SuspenseList");
|
|
41879
41879
|
break;
|
|
41880
41880
|
case ViewTransitionComponent:
|
|
41881
|
-
|
|
41881
|
+
info2 += describeBuiltInComponentFrame("ViewTransition");
|
|
41882
41882
|
break;
|
|
41883
41883
|
case ActivityComponent:
|
|
41884
|
-
|
|
41884
|
+
info2 += describeBuiltInComponentFrame("Activity");
|
|
41885
41885
|
break;
|
|
41886
41886
|
}
|
|
41887
41887
|
var owner = workInProgress;
|
|
@@ -41895,7 +41895,7 @@ Error generating stack: ` + x.message + `
|
|
|
41895
41895
|
debugStack = formatOwnerStack(debugStack);
|
|
41896
41896
|
}
|
|
41897
41897
|
if (debugStack !== "") {
|
|
41898
|
-
|
|
41898
|
+
info2 += `
|
|
41899
41899
|
` + debugStack;
|
|
41900
41900
|
}
|
|
41901
41901
|
}
|
|
@@ -41903,14 +41903,14 @@ Error generating stack: ` + x.message + `
|
|
|
41903
41903
|
var ownerStack = owner.debugStack;
|
|
41904
41904
|
owner = owner.owner;
|
|
41905
41905
|
if (owner && ownerStack) {
|
|
41906
|
-
|
|
41906
|
+
info2 += `
|
|
41907
41907
|
` + formatOwnerStack(ownerStack);
|
|
41908
41908
|
}
|
|
41909
41909
|
} else {
|
|
41910
41910
|
break;
|
|
41911
41911
|
}
|
|
41912
41912
|
}
|
|
41913
|
-
return
|
|
41913
|
+
return info2;
|
|
41914
41914
|
} catch (x) {
|
|
41915
41915
|
return `
|
|
41916
41916
|
Error generating stack: ` + x.message + `
|
|
@@ -59652,13 +59652,1328 @@ var init_command11 = __esm(async () => {
|
|
|
59652
59652
|
});
|
|
59653
59653
|
});
|
|
59654
59654
|
|
|
59655
|
+
// src/lib/hooks/find-room.ts
|
|
59656
|
+
import { readdirSync, readFileSync as readFileSync4 } from "node:fs";
|
|
59657
|
+
import { join as join3 } from "node:path";
|
|
59658
|
+
function findRoomId(sessionId, teamsDir) {
|
|
59659
|
+
const dir = teamsDir ?? `${process.env.HOME}/.claude/teams`;
|
|
59660
|
+
let entries;
|
|
59661
|
+
try {
|
|
59662
|
+
entries = readdirSync(dir);
|
|
59663
|
+
} catch {
|
|
59664
|
+
return null;
|
|
59665
|
+
}
|
|
59666
|
+
for (const entry of entries) {
|
|
59667
|
+
const filePath = join3(dir, entry, "meet-ai.json");
|
|
59668
|
+
try {
|
|
59669
|
+
const raw = readFileSync4(filePath, "utf-8");
|
|
59670
|
+
const data = JSON.parse(raw);
|
|
59671
|
+
if (data.session_id === sessionId) {
|
|
59672
|
+
return data.room_id || null;
|
|
59673
|
+
}
|
|
59674
|
+
} catch {
|
|
59675
|
+
continue;
|
|
59676
|
+
}
|
|
59677
|
+
}
|
|
59678
|
+
return null;
|
|
59679
|
+
}
|
|
59680
|
+
var init_find_room = () => {};
|
|
59681
|
+
|
|
59682
|
+
// src/lib/hooks/summarize.ts
|
|
59683
|
+
import { basename } from "node:path";
|
|
59684
|
+
function summarize(toolName, toolInput) {
|
|
59685
|
+
const str = (key) => typeof toolInput[key] === "string" ? toolInput[key] : "";
|
|
59686
|
+
const file2 = (key) => basename(str(key)) || "?";
|
|
59687
|
+
switch (toolName) {
|
|
59688
|
+
case "Edit": {
|
|
59689
|
+
return `Edit: ${file2("file_path")}`;
|
|
59690
|
+
}
|
|
59691
|
+
case "Read": {
|
|
59692
|
+
return `Read: ${file2("file_path")}`;
|
|
59693
|
+
}
|
|
59694
|
+
case "Write": {
|
|
59695
|
+
return `Write: ${file2("file_path")}`;
|
|
59696
|
+
}
|
|
59697
|
+
case "Bash": {
|
|
59698
|
+
return `Bash: ${truncate(str("command"), 60)}`;
|
|
59699
|
+
}
|
|
59700
|
+
case "Grep": {
|
|
59701
|
+
return `Grep: "${str("pattern")}" in ${str("glob") || str("path")}`;
|
|
59702
|
+
}
|
|
59703
|
+
case "Glob": {
|
|
59704
|
+
return `Glob: ${str("pattern")}`;
|
|
59705
|
+
}
|
|
59706
|
+
case "Task": {
|
|
59707
|
+
return `Task: ${truncate(str("description"), 60)}`;
|
|
59708
|
+
}
|
|
59709
|
+
case "WebFetch": {
|
|
59710
|
+
return `WebFetch: ${str("url")}`;
|
|
59711
|
+
}
|
|
59712
|
+
case "WebSearch": {
|
|
59713
|
+
return `WebSearch: ${str("query")}`;
|
|
59714
|
+
}
|
|
59715
|
+
default: {
|
|
59716
|
+
return toolName;
|
|
59717
|
+
}
|
|
59718
|
+
}
|
|
59719
|
+
}
|
|
59720
|
+
var truncate = (s, n) => s.slice(0, n);
|
|
59721
|
+
var init_summarize = () => {};
|
|
59722
|
+
|
|
59723
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/utils/url.js
|
|
59724
|
+
var init_url = () => {};
|
|
59725
|
+
|
|
59726
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/utils/cookie.js
|
|
59727
|
+
var _serialize = (name, value, opt = {}) => {
|
|
59728
|
+
let cookie = `${name}=${value}`;
|
|
59729
|
+
if (name.startsWith("__Secure-") && !opt.secure) {
|
|
59730
|
+
throw new Error("__Secure- Cookie must have Secure attributes");
|
|
59731
|
+
}
|
|
59732
|
+
if (name.startsWith("__Host-")) {
|
|
59733
|
+
if (!opt.secure) {
|
|
59734
|
+
throw new Error("__Host- Cookie must have Secure attributes");
|
|
59735
|
+
}
|
|
59736
|
+
if (opt.path !== "/") {
|
|
59737
|
+
throw new Error('__Host- Cookie must have Path attributes with "/"');
|
|
59738
|
+
}
|
|
59739
|
+
if (opt.domain) {
|
|
59740
|
+
throw new Error("__Host- Cookie must not have Domain attributes");
|
|
59741
|
+
}
|
|
59742
|
+
}
|
|
59743
|
+
if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
|
|
59744
|
+
if (opt.maxAge > 34560000) {
|
|
59745
|
+
throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");
|
|
59746
|
+
}
|
|
59747
|
+
cookie += `; Max-Age=${opt.maxAge | 0}`;
|
|
59748
|
+
}
|
|
59749
|
+
if (opt.domain && opt.prefix !== "host") {
|
|
59750
|
+
cookie += `; Domain=${opt.domain}`;
|
|
59751
|
+
}
|
|
59752
|
+
if (opt.path) {
|
|
59753
|
+
cookie += `; Path=${opt.path}`;
|
|
59754
|
+
}
|
|
59755
|
+
if (opt.expires) {
|
|
59756
|
+
if (opt.expires.getTime() - Date.now() > 34560000000) {
|
|
59757
|
+
throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");
|
|
59758
|
+
}
|
|
59759
|
+
cookie += `; Expires=${opt.expires.toUTCString()}`;
|
|
59760
|
+
}
|
|
59761
|
+
if (opt.httpOnly) {
|
|
59762
|
+
cookie += "; HttpOnly";
|
|
59763
|
+
}
|
|
59764
|
+
if (opt.secure) {
|
|
59765
|
+
cookie += "; Secure";
|
|
59766
|
+
}
|
|
59767
|
+
if (opt.sameSite) {
|
|
59768
|
+
cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`;
|
|
59769
|
+
}
|
|
59770
|
+
if (opt.priority) {
|
|
59771
|
+
cookie += `; Priority=${opt.priority.charAt(0).toUpperCase() + opt.priority.slice(1)}`;
|
|
59772
|
+
}
|
|
59773
|
+
if (opt.partitioned) {
|
|
59774
|
+
if (!opt.secure) {
|
|
59775
|
+
throw new Error("Partitioned Cookie must have Secure attributes");
|
|
59776
|
+
}
|
|
59777
|
+
cookie += "; Partitioned";
|
|
59778
|
+
}
|
|
59779
|
+
return cookie;
|
|
59780
|
+
}, serialize = (name, value, opt) => {
|
|
59781
|
+
value = encodeURIComponent(value);
|
|
59782
|
+
return _serialize(name, value, opt);
|
|
59783
|
+
};
|
|
59784
|
+
var init_cookie = __esm(() => {
|
|
59785
|
+
init_url();
|
|
59786
|
+
});
|
|
59787
|
+
|
|
59788
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/fetch-result-please.js
|
|
59789
|
+
var init_fetch_result_please = () => {};
|
|
59790
|
+
|
|
59791
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/utils.js
|
|
59792
|
+
function isObject2(item) {
|
|
59793
|
+
return typeof item === "object" && item !== null && !Array.isArray(item);
|
|
59794
|
+
}
|
|
59795
|
+
function deepMerge(target, source) {
|
|
59796
|
+
if (!isObject2(target) && !isObject2(source)) {
|
|
59797
|
+
return source;
|
|
59798
|
+
}
|
|
59799
|
+
const merged = { ...target };
|
|
59800
|
+
for (const key in source) {
|
|
59801
|
+
const value = source[key];
|
|
59802
|
+
if (isObject2(merged[key]) && isObject2(value)) {
|
|
59803
|
+
merged[key] = deepMerge(merged[key], value);
|
|
59804
|
+
} else {
|
|
59805
|
+
merged[key] = value;
|
|
59806
|
+
}
|
|
59807
|
+
}
|
|
59808
|
+
return merged;
|
|
59809
|
+
}
|
|
59810
|
+
var mergePath = (base2, path) => {
|
|
59811
|
+
base2 = base2.replace(/\/+$/, "");
|
|
59812
|
+
base2 = base2 + "/";
|
|
59813
|
+
path = path.replace(/^\/+/, "");
|
|
59814
|
+
return base2 + path;
|
|
59815
|
+
}, replaceUrlParam = (urlString, params) => {
|
|
59816
|
+
for (const [k, v] of Object.entries(params)) {
|
|
59817
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
59818
|
+
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
59819
|
+
}
|
|
59820
|
+
return urlString;
|
|
59821
|
+
}, buildSearchParams = (query) => {
|
|
59822
|
+
const searchParams = new URLSearchParams;
|
|
59823
|
+
for (const [k, v] of Object.entries(query)) {
|
|
59824
|
+
if (v === undefined) {
|
|
59825
|
+
continue;
|
|
59826
|
+
}
|
|
59827
|
+
if (Array.isArray(v)) {
|
|
59828
|
+
for (const v2 of v) {
|
|
59829
|
+
searchParams.append(k, v2);
|
|
59830
|
+
}
|
|
59831
|
+
} else {
|
|
59832
|
+
searchParams.set(k, v);
|
|
59833
|
+
}
|
|
59834
|
+
}
|
|
59835
|
+
return searchParams;
|
|
59836
|
+
}, replaceUrlProtocol = (urlString, protocol) => {
|
|
59837
|
+
switch (protocol) {
|
|
59838
|
+
case "ws":
|
|
59839
|
+
return urlString.replace(/^http/, "ws");
|
|
59840
|
+
case "http":
|
|
59841
|
+
return urlString.replace(/^ws/, "http");
|
|
59842
|
+
}
|
|
59843
|
+
}, removeIndexString = (urlString) => {
|
|
59844
|
+
if (/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test(urlString)) {
|
|
59845
|
+
return urlString.replace(/\/index(?=\?|$)/, "/");
|
|
59846
|
+
}
|
|
59847
|
+
return urlString.replace(/\/index(?=\?|$)/, "");
|
|
59848
|
+
};
|
|
59849
|
+
var init_utils2 = __esm(() => {
|
|
59850
|
+
init_fetch_result_please();
|
|
59851
|
+
});
|
|
59852
|
+
|
|
59853
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/client.js
|
|
59854
|
+
var createProxy = (callback, path) => {
|
|
59855
|
+
const proxy = new Proxy(() => {}, {
|
|
59856
|
+
get(_obj, key) {
|
|
59857
|
+
if (typeof key !== "string" || key === "then") {
|
|
59858
|
+
return;
|
|
59859
|
+
}
|
|
59860
|
+
return createProxy(callback, [...path, key]);
|
|
59861
|
+
},
|
|
59862
|
+
apply(_1, _2, args) {
|
|
59863
|
+
return callback({
|
|
59864
|
+
path,
|
|
59865
|
+
args
|
|
59866
|
+
});
|
|
59867
|
+
}
|
|
59868
|
+
});
|
|
59869
|
+
return proxy;
|
|
59870
|
+
}, ClientRequestImpl = class {
|
|
59871
|
+
url;
|
|
59872
|
+
method;
|
|
59873
|
+
buildSearchParams;
|
|
59874
|
+
queryParams = undefined;
|
|
59875
|
+
pathParams = {};
|
|
59876
|
+
rBody;
|
|
59877
|
+
cType = undefined;
|
|
59878
|
+
constructor(url2, method, options) {
|
|
59879
|
+
this.url = url2;
|
|
59880
|
+
this.method = method;
|
|
59881
|
+
this.buildSearchParams = options.buildSearchParams;
|
|
59882
|
+
}
|
|
59883
|
+
fetch = async (args, opt) => {
|
|
59884
|
+
if (args) {
|
|
59885
|
+
if (args.query) {
|
|
59886
|
+
this.queryParams = this.buildSearchParams(args.query);
|
|
59887
|
+
}
|
|
59888
|
+
if (args.form) {
|
|
59889
|
+
const form = new FormData;
|
|
59890
|
+
for (const [k, v] of Object.entries(args.form)) {
|
|
59891
|
+
if (Array.isArray(v)) {
|
|
59892
|
+
for (const v2 of v) {
|
|
59893
|
+
form.append(k, v2);
|
|
59894
|
+
}
|
|
59895
|
+
} else {
|
|
59896
|
+
form.append(k, v);
|
|
59897
|
+
}
|
|
59898
|
+
}
|
|
59899
|
+
this.rBody = form;
|
|
59900
|
+
}
|
|
59901
|
+
if (args.json) {
|
|
59902
|
+
this.rBody = JSON.stringify(args.json);
|
|
59903
|
+
this.cType = "application/json";
|
|
59904
|
+
}
|
|
59905
|
+
if (args.param) {
|
|
59906
|
+
this.pathParams = args.param;
|
|
59907
|
+
}
|
|
59908
|
+
}
|
|
59909
|
+
let methodUpperCase = this.method.toUpperCase();
|
|
59910
|
+
const headerValues = {
|
|
59911
|
+
...args?.header,
|
|
59912
|
+
...typeof opt?.headers === "function" ? await opt.headers() : opt?.headers
|
|
59913
|
+
};
|
|
59914
|
+
if (args?.cookie) {
|
|
59915
|
+
const cookies = [];
|
|
59916
|
+
for (const [key, value] of Object.entries(args.cookie)) {
|
|
59917
|
+
cookies.push(serialize(key, value, { path: "/" }));
|
|
59918
|
+
}
|
|
59919
|
+
headerValues["Cookie"] = cookies.join(",");
|
|
59920
|
+
}
|
|
59921
|
+
if (this.cType) {
|
|
59922
|
+
headerValues["Content-Type"] = this.cType;
|
|
59923
|
+
}
|
|
59924
|
+
const headers = new Headers(headerValues ?? undefined);
|
|
59925
|
+
let url2 = this.url;
|
|
59926
|
+
url2 = removeIndexString(url2);
|
|
59927
|
+
url2 = replaceUrlParam(url2, this.pathParams);
|
|
59928
|
+
if (this.queryParams) {
|
|
59929
|
+
url2 = url2 + "?" + this.queryParams.toString();
|
|
59930
|
+
}
|
|
59931
|
+
methodUpperCase = this.method.toUpperCase();
|
|
59932
|
+
const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
|
|
59933
|
+
return (opt?.fetch || fetch)(url2, {
|
|
59934
|
+
body: setBody ? this.rBody : undefined,
|
|
59935
|
+
method: methodUpperCase,
|
|
59936
|
+
headers,
|
|
59937
|
+
...opt?.init
|
|
59938
|
+
});
|
|
59939
|
+
};
|
|
59940
|
+
}, hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
59941
|
+
const buildSearchParamsOption = options?.buildSearchParams ?? buildSearchParams;
|
|
59942
|
+
const parts = [...opts.path];
|
|
59943
|
+
const lastParts = parts.slice(-3).reverse();
|
|
59944
|
+
if (lastParts[0] === "toString") {
|
|
59945
|
+
if (lastParts[1] === "name") {
|
|
59946
|
+
return lastParts[2] || "";
|
|
59947
|
+
}
|
|
59948
|
+
return proxyCallback.toString();
|
|
59949
|
+
}
|
|
59950
|
+
if (lastParts[0] === "valueOf") {
|
|
59951
|
+
if (lastParts[1] === "name") {
|
|
59952
|
+
return lastParts[2] || "";
|
|
59953
|
+
}
|
|
59954
|
+
return proxyCallback;
|
|
59955
|
+
}
|
|
59956
|
+
let method = "";
|
|
59957
|
+
if (/^\$/.test(lastParts[0])) {
|
|
59958
|
+
const last = parts.pop();
|
|
59959
|
+
if (last) {
|
|
59960
|
+
method = last.replace(/^\$/, "");
|
|
59961
|
+
}
|
|
59962
|
+
}
|
|
59963
|
+
const path = parts.join("/");
|
|
59964
|
+
const url2 = mergePath(baseUrl, path);
|
|
59965
|
+
if (method === "url") {
|
|
59966
|
+
let result = url2;
|
|
59967
|
+
if (opts.args[0]) {
|
|
59968
|
+
if (opts.args[0].param) {
|
|
59969
|
+
result = replaceUrlParam(url2, opts.args[0].param);
|
|
59970
|
+
}
|
|
59971
|
+
if (opts.args[0].query) {
|
|
59972
|
+
result = result + "?" + buildSearchParamsOption(opts.args[0].query).toString();
|
|
59973
|
+
}
|
|
59974
|
+
}
|
|
59975
|
+
result = removeIndexString(result);
|
|
59976
|
+
return new URL(result);
|
|
59977
|
+
}
|
|
59978
|
+
if (method === "ws") {
|
|
59979
|
+
const webSocketUrl = replaceUrlProtocol(opts.args[0] && opts.args[0].param ? replaceUrlParam(url2, opts.args[0].param) : url2, "ws");
|
|
59980
|
+
const targetUrl = new URL(webSocketUrl);
|
|
59981
|
+
const queryParams = opts.args[0]?.query;
|
|
59982
|
+
if (queryParams) {
|
|
59983
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
59984
|
+
if (Array.isArray(value)) {
|
|
59985
|
+
value.forEach((item) => targetUrl.searchParams.append(key, item));
|
|
59986
|
+
} else {
|
|
59987
|
+
targetUrl.searchParams.set(key, value);
|
|
59988
|
+
}
|
|
59989
|
+
});
|
|
59990
|
+
}
|
|
59991
|
+
const establishWebSocket = (...args) => {
|
|
59992
|
+
if (options?.webSocket !== undefined && typeof options.webSocket === "function") {
|
|
59993
|
+
return options.webSocket(...args);
|
|
59994
|
+
}
|
|
59995
|
+
return new WebSocket(...args);
|
|
59996
|
+
};
|
|
59997
|
+
return establishWebSocket(targetUrl.toString());
|
|
59998
|
+
}
|
|
59999
|
+
const req = new ClientRequestImpl(url2, method, {
|
|
60000
|
+
buildSearchParams: buildSearchParamsOption
|
|
60001
|
+
});
|
|
60002
|
+
if (method) {
|
|
60003
|
+
options ??= {};
|
|
60004
|
+
const args = deepMerge(options, { ...opts.args[1] });
|
|
60005
|
+
return req.fetch(opts.args[0], args);
|
|
60006
|
+
}
|
|
60007
|
+
return req;
|
|
60008
|
+
}, []);
|
|
60009
|
+
var init_client2 = __esm(() => {
|
|
60010
|
+
init_cookie();
|
|
60011
|
+
init_utils2();
|
|
60012
|
+
});
|
|
60013
|
+
|
|
60014
|
+
// ../../node_modules/.bun/hono@4.11.8/node_modules/hono/dist/client/index.js
|
|
60015
|
+
var init_client3 = __esm(() => {
|
|
60016
|
+
init_client2();
|
|
60017
|
+
init_utils2();
|
|
60018
|
+
});
|
|
60019
|
+
|
|
60020
|
+
// src/lib/hooks/client.ts
|
|
60021
|
+
function createHookClient(url2, key) {
|
|
60022
|
+
return hc(url2, {
|
|
60023
|
+
headers: {
|
|
60024
|
+
"Content-Type": "application/json",
|
|
60025
|
+
Authorization: `Bearer ${key}`
|
|
60026
|
+
}
|
|
60027
|
+
});
|
|
60028
|
+
}
|
|
60029
|
+
async function sendParentMessage(client, roomId) {
|
|
60030
|
+
try {
|
|
60031
|
+
const res = await client.api.rooms[":id"].messages.$post({
|
|
60032
|
+
param: { id: roomId },
|
|
60033
|
+
json: {
|
|
60034
|
+
sender: HOOK_SENDER,
|
|
60035
|
+
content: "Agent activity",
|
|
60036
|
+
sender_type: "agent",
|
|
60037
|
+
color: HOOK_COLOR
|
|
60038
|
+
}
|
|
60039
|
+
});
|
|
60040
|
+
if (!res.ok)
|
|
60041
|
+
return null;
|
|
60042
|
+
const data = await res.json();
|
|
60043
|
+
return data.id;
|
|
60044
|
+
} catch {
|
|
60045
|
+
return null;
|
|
60046
|
+
}
|
|
60047
|
+
}
|
|
60048
|
+
async function sendLogEntry(client, roomId, summary, messageId) {
|
|
60049
|
+
try {
|
|
60050
|
+
await client.api.rooms[":id"].logs.$post({
|
|
60051
|
+
param: { id: roomId },
|
|
60052
|
+
json: {
|
|
60053
|
+
sender: HOOK_SENDER,
|
|
60054
|
+
content: summary,
|
|
60055
|
+
color: HOOK_COLOR,
|
|
60056
|
+
...messageId ? { message_id: messageId } : {}
|
|
60057
|
+
}
|
|
60058
|
+
});
|
|
60059
|
+
} catch {}
|
|
60060
|
+
}
|
|
60061
|
+
var HOOK_COLOR = "#6b7280", HOOK_SENDER = "hook";
|
|
60062
|
+
var init_client4 = __esm(() => {
|
|
60063
|
+
init_client3();
|
|
60064
|
+
});
|
|
60065
|
+
|
|
60066
|
+
// src/lib/hooks/index.ts
|
|
60067
|
+
var init_hooks = __esm(() => {
|
|
60068
|
+
init_find_room();
|
|
60069
|
+
init_summarize();
|
|
60070
|
+
init_client4();
|
|
60071
|
+
});
|
|
60072
|
+
|
|
60073
|
+
// src/commands/hook/log-tool-use/usecase.ts
|
|
60074
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, statSync as statSync2, rmSync } from "node:fs";
|
|
60075
|
+
function getOrCreateParentId(sessionId) {
|
|
60076
|
+
const path = `/tmp/meet-ai-hook-${sessionId}.msgid`;
|
|
60077
|
+
try {
|
|
60078
|
+
const mtime = statSync2(path).mtimeMs;
|
|
60079
|
+
if (Date.now() - mtime > PARENT_MSG_TTL_SEC * 1000) {
|
|
60080
|
+
rmSync(path, { force: true });
|
|
60081
|
+
return null;
|
|
60082
|
+
}
|
|
60083
|
+
return readFileSync5(path, "utf-8").trim() || null;
|
|
60084
|
+
} catch {
|
|
60085
|
+
return null;
|
|
60086
|
+
}
|
|
60087
|
+
}
|
|
60088
|
+
function saveParentId(sessionId, msgId) {
|
|
60089
|
+
try {
|
|
60090
|
+
writeFileSync2(`/tmp/meet-ai-hook-${sessionId}.msgid`, msgId);
|
|
60091
|
+
} catch {}
|
|
60092
|
+
}
|
|
60093
|
+
async function processHookInput(rawInput, teamsDir) {
|
|
60094
|
+
let input;
|
|
60095
|
+
try {
|
|
60096
|
+
input = JSON.parse(rawInput);
|
|
60097
|
+
} catch {
|
|
60098
|
+
return "skip";
|
|
60099
|
+
}
|
|
60100
|
+
const { session_id: sessionId, tool_name: toolName, tool_input: toolInput = {} } = input;
|
|
60101
|
+
if (!sessionId || !toolName)
|
|
60102
|
+
return "skip";
|
|
60103
|
+
if (toolName === "SendMessage")
|
|
60104
|
+
return "skip";
|
|
60105
|
+
if (toolName === "Bash") {
|
|
60106
|
+
const cmd = typeof toolInput.command === "string" ? toolInput.command : "";
|
|
60107
|
+
if (cmd.startsWith("cd ") || cmd.startsWith("meet-ai "))
|
|
60108
|
+
return "skip";
|
|
60109
|
+
}
|
|
60110
|
+
const roomId = findRoomId(sessionId, teamsDir);
|
|
60111
|
+
if (!roomId)
|
|
60112
|
+
return "skip";
|
|
60113
|
+
const url2 = process.env.MEET_AI_URL;
|
|
60114
|
+
const key = process.env.MEET_AI_KEY;
|
|
60115
|
+
if (!url2 || !key)
|
|
60116
|
+
return "skip";
|
|
60117
|
+
const client = createHookClient(url2, key);
|
|
60118
|
+
const summary = summarize(toolName, toolInput);
|
|
60119
|
+
let parentId = getOrCreateParentId(sessionId);
|
|
60120
|
+
if (!parentId) {
|
|
60121
|
+
parentId = await sendParentMessage(client, roomId);
|
|
60122
|
+
if (parentId)
|
|
60123
|
+
saveParentId(sessionId, parentId);
|
|
60124
|
+
}
|
|
60125
|
+
await sendLogEntry(client, roomId, summary, parentId ?? undefined);
|
|
60126
|
+
return "sent";
|
|
60127
|
+
}
|
|
60128
|
+
var PARENT_MSG_TTL_SEC = 120;
|
|
60129
|
+
var init_usecase11 = __esm(() => {
|
|
60130
|
+
init_hooks();
|
|
60131
|
+
init_hooks();
|
|
60132
|
+
init_hooks();
|
|
60133
|
+
});
|
|
60134
|
+
|
|
60135
|
+
// src/commands/hook/log-tool-use/command.ts
|
|
60136
|
+
var exports_command12 = {};
|
|
60137
|
+
__export(exports_command12, {
|
|
60138
|
+
default: () => command_default12
|
|
60139
|
+
});
|
|
60140
|
+
var command_default12;
|
|
60141
|
+
var init_command12 = __esm(() => {
|
|
60142
|
+
init_dist();
|
|
60143
|
+
init_usecase11();
|
|
60144
|
+
command_default12 = defineCommand({
|
|
60145
|
+
meta: {
|
|
60146
|
+
name: "log-tool-use",
|
|
60147
|
+
description: "Hook: log tool use events to a chat room"
|
|
60148
|
+
},
|
|
60149
|
+
async run() {
|
|
60150
|
+
try {
|
|
60151
|
+
let input = "";
|
|
60152
|
+
for await (const chunk of process.stdin) {
|
|
60153
|
+
input += chunk;
|
|
60154
|
+
}
|
|
60155
|
+
await processHookInput(input);
|
|
60156
|
+
} catch {}
|
|
60157
|
+
process.exit(0);
|
|
60158
|
+
}
|
|
60159
|
+
});
|
|
60160
|
+
});
|
|
60161
|
+
|
|
60162
|
+
// src/commands/hook/plan-review/usecase.ts
|
|
60163
|
+
var exports_usecase2 = {};
|
|
60164
|
+
__export(exports_usecase2, {
|
|
60165
|
+
processPlanReview: () => processPlanReview
|
|
60166
|
+
});
|
|
60167
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
60168
|
+
async function createPlanReview(client, roomId, planContent) {
|
|
60169
|
+
try {
|
|
60170
|
+
const res = await client.api.rooms[":id"]["plan-reviews"].$post({
|
|
60171
|
+
param: { id: roomId },
|
|
60172
|
+
json: { plan_content: planContent }
|
|
60173
|
+
});
|
|
60174
|
+
if (!res.ok) {
|
|
60175
|
+
const text = await res.text();
|
|
60176
|
+
process.stderr.write(`[plan-review] create failed: ${res.status} ${text}
|
|
60177
|
+
`);
|
|
60178
|
+
return null;
|
|
60179
|
+
}
|
|
60180
|
+
return await res.json();
|
|
60181
|
+
} catch (error48) {
|
|
60182
|
+
process.stderr.write(`[plan-review] create error: ${error48}
|
|
60183
|
+
`);
|
|
60184
|
+
return null;
|
|
60185
|
+
}
|
|
60186
|
+
}
|
|
60187
|
+
async function pollForDecision(client, roomId, reviewId) {
|
|
60188
|
+
const deadline = Date.now() + POLL_TIMEOUT_MS;
|
|
60189
|
+
while (Date.now() < deadline) {
|
|
60190
|
+
try {
|
|
60191
|
+
const res = await client.api.rooms[":id"]["plan-reviews"][":reviewId"].$get({
|
|
60192
|
+
param: { id: roomId, reviewId }
|
|
60193
|
+
});
|
|
60194
|
+
if (res.ok) {
|
|
60195
|
+
const data = await res.json();
|
|
60196
|
+
if (data.status !== "pending") {
|
|
60197
|
+
return data;
|
|
60198
|
+
}
|
|
60199
|
+
}
|
|
60200
|
+
} catch (error48) {
|
|
60201
|
+
process.stderr.write(`[plan-review] poll error: ${error48}
|
|
60202
|
+
`);
|
|
60203
|
+
}
|
|
60204
|
+
await delay(POLL_INTERVAL_MS);
|
|
60205
|
+
}
|
|
60206
|
+
return null;
|
|
60207
|
+
}
|
|
60208
|
+
function getPromptsByMode(mode) {
|
|
60209
|
+
switch (mode) {
|
|
60210
|
+
case "acceptEdits": {
|
|
60211
|
+
return [
|
|
60212
|
+
{ tool: "Bash", prompt: "install dependencies" },
|
|
60213
|
+
{ tool: "Bash", prompt: "run tests" },
|
|
60214
|
+
{ tool: "Bash", prompt: "run build" },
|
|
60215
|
+
{ tool: "Bash", prompt: "run typecheck" },
|
|
60216
|
+
{ tool: "Bash", prompt: "run linter" }
|
|
60217
|
+
];
|
|
60218
|
+
}
|
|
60219
|
+
case "bypassPermissions": {
|
|
60220
|
+
return [{ tool: "Bash", prompt: "run any command" }];
|
|
60221
|
+
}
|
|
60222
|
+
default: {
|
|
60223
|
+
return;
|
|
60224
|
+
}
|
|
60225
|
+
}
|
|
60226
|
+
}
|
|
60227
|
+
function buildAllowOutput(permissionMode) {
|
|
60228
|
+
const allowedPrompts = getPromptsByMode(permissionMode);
|
|
60229
|
+
return {
|
|
60230
|
+
hookSpecificOutput: {
|
|
60231
|
+
hookEventName: "PermissionRequest",
|
|
60232
|
+
decision: allowedPrompts ? { behavior: "allow", allowedPrompts } : { behavior: "allow" }
|
|
60233
|
+
}
|
|
60234
|
+
};
|
|
60235
|
+
}
|
|
60236
|
+
function buildDenyOutput(feedback) {
|
|
60237
|
+
return {
|
|
60238
|
+
hookSpecificOutput: {
|
|
60239
|
+
hookEventName: "PermissionRequest",
|
|
60240
|
+
decision: {
|
|
60241
|
+
behavior: "deny",
|
|
60242
|
+
message: feedback
|
|
60243
|
+
}
|
|
60244
|
+
}
|
|
60245
|
+
};
|
|
60246
|
+
}
|
|
60247
|
+
async function expirePlanReview(client, roomId, reviewId) {
|
|
60248
|
+
try {
|
|
60249
|
+
await client.api.rooms[":id"]["plan-reviews"][":reviewId"].expire.$post({
|
|
60250
|
+
param: { id: roomId, reviewId }
|
|
60251
|
+
});
|
|
60252
|
+
} catch {}
|
|
60253
|
+
}
|
|
60254
|
+
async function processPlanReview(rawInput, teamsDir) {
|
|
60255
|
+
let input;
|
|
60256
|
+
try {
|
|
60257
|
+
input = JSON.parse(rawInput);
|
|
60258
|
+
} catch {
|
|
60259
|
+
process.stderr.write(`[plan-review] failed to parse stdin
|
|
60260
|
+
`);
|
|
60261
|
+
return;
|
|
60262
|
+
}
|
|
60263
|
+
const { session_id: sessionId } = input;
|
|
60264
|
+
if (!sessionId) {
|
|
60265
|
+
process.stderr.write(`[plan-review] missing session_id
|
|
60266
|
+
`);
|
|
60267
|
+
return;
|
|
60268
|
+
}
|
|
60269
|
+
const planContent = input.tool_input?.plan || "_Agent requested to exit plan mode without a plan._";
|
|
60270
|
+
const roomId = findRoomId(sessionId, teamsDir);
|
|
60271
|
+
if (!roomId) {
|
|
60272
|
+
process.stderr.write(`[plan-review] no room found for session
|
|
60273
|
+
`);
|
|
60274
|
+
return;
|
|
60275
|
+
}
|
|
60276
|
+
const url2 = process.env.MEET_AI_URL;
|
|
60277
|
+
const key = process.env.MEET_AI_KEY;
|
|
60278
|
+
if (!url2 || !key) {
|
|
60279
|
+
process.stderr.write(`[plan-review] MEET_AI_URL or MEET_AI_KEY not set
|
|
60280
|
+
`);
|
|
60281
|
+
return;
|
|
60282
|
+
}
|
|
60283
|
+
const client = createHookClient(url2, key);
|
|
60284
|
+
process.stderr.write(`[plan-review] sending plan to room ${roomId} via ${url2}
|
|
60285
|
+
`);
|
|
60286
|
+
const review = await createPlanReview(client, roomId, planContent);
|
|
60287
|
+
if (!review)
|
|
60288
|
+
return;
|
|
60289
|
+
process.stderr.write(`[plan-review] plan review created: ${review.id}, polling for decision...
|
|
60290
|
+
`);
|
|
60291
|
+
const decision = await pollForDecision(client, roomId, review.id);
|
|
60292
|
+
if (!decision) {
|
|
60293
|
+
process.stderr.write(`[plan-review] timed out waiting for decision
|
|
60294
|
+
`);
|
|
60295
|
+
await expirePlanReview(client, roomId, review.id);
|
|
60296
|
+
return;
|
|
60297
|
+
}
|
|
60298
|
+
process.stderr.write(`[plan-review] decision: ${decision.status}
|
|
60299
|
+
`);
|
|
60300
|
+
if (decision.status === "approved" || decision.status === "expired") {
|
|
60301
|
+
process.stdout.write(JSON.stringify(buildAllowOutput(decision.permission_mode)));
|
|
60302
|
+
} else if (decision.status === "denied") {
|
|
60303
|
+
const feedback = decision.feedback || "Plan was rejected. Please revise the plan based on the feedback.";
|
|
60304
|
+
process.stdout.write(JSON.stringify(buildDenyOutput(feedback)));
|
|
60305
|
+
}
|
|
60306
|
+
}
|
|
60307
|
+
var POLL_INTERVAL_MS = 2000, POLL_TIMEOUT_MS = 2592000000;
|
|
60308
|
+
var init_usecase12 = __esm(() => {
|
|
60309
|
+
init_client4();
|
|
60310
|
+
init_find_room();
|
|
60311
|
+
});
|
|
60312
|
+
|
|
60313
|
+
// src/commands/hook/plan-review/command.ts
|
|
60314
|
+
var exports_command13 = {};
|
|
60315
|
+
__export(exports_command13, {
|
|
60316
|
+
default: () => command_default13
|
|
60317
|
+
});
|
|
60318
|
+
var command_default13;
|
|
60319
|
+
var init_command13 = __esm(() => {
|
|
60320
|
+
init_dist();
|
|
60321
|
+
command_default13 = defineCommand({
|
|
60322
|
+
meta: {
|
|
60323
|
+
name: "plan-review",
|
|
60324
|
+
description: "Claude Code hook: send plan for review and poll for decision"
|
|
60325
|
+
},
|
|
60326
|
+
async run() {
|
|
60327
|
+
try {
|
|
60328
|
+
let input = "";
|
|
60329
|
+
for await (const chunk of process.stdin) {
|
|
60330
|
+
input += chunk;
|
|
60331
|
+
}
|
|
60332
|
+
const { processPlanReview: processPlanReview2 } = await Promise.resolve().then(() => (init_usecase12(), exports_usecase2));
|
|
60333
|
+
await processPlanReview2(input);
|
|
60334
|
+
} catch (error48) {
|
|
60335
|
+
process.stderr.write(`[plan-review] fatal: ${error48}
|
|
60336
|
+
`);
|
|
60337
|
+
}
|
|
60338
|
+
process.exit(0);
|
|
60339
|
+
}
|
|
60340
|
+
});
|
|
60341
|
+
});
|
|
60342
|
+
|
|
60343
|
+
// src/commands/hook/question-review/usecase.ts
|
|
60344
|
+
function formatQuestions(questions) {
|
|
60345
|
+
return questions.map((q) => {
|
|
60346
|
+
let text = `**${q.question}**
|
|
60347
|
+
`;
|
|
60348
|
+
for (let i = 0;i < q.options.length; i++) {
|
|
60349
|
+
const opt = q.options[i];
|
|
60350
|
+
text += `${i + 1}. **${opt.label}**`;
|
|
60351
|
+
if (opt.description)
|
|
60352
|
+
text += ` — ${opt.description}`;
|
|
60353
|
+
text += `
|
|
60354
|
+
`;
|
|
60355
|
+
}
|
|
60356
|
+
if (q.multiSelect) {
|
|
60357
|
+
text += `
|
|
60358
|
+
_Multiple choices allowed._`;
|
|
60359
|
+
}
|
|
60360
|
+
return text;
|
|
60361
|
+
}).join(`
|
|
60362
|
+
|
|
60363
|
+
`);
|
|
60364
|
+
}
|
|
60365
|
+
async function createQuestionReview(client, roomId, questions, formattedContent) {
|
|
60366
|
+
try {
|
|
60367
|
+
const res = await client.api.rooms[":id"]["question-reviews"].$post({
|
|
60368
|
+
param: { id: roomId },
|
|
60369
|
+
json: {
|
|
60370
|
+
questions_json: JSON.stringify(questions),
|
|
60371
|
+
formatted_content: formattedContent
|
|
60372
|
+
}
|
|
60373
|
+
});
|
|
60374
|
+
if (!res.ok) {
|
|
60375
|
+
const text = await res.text();
|
|
60376
|
+
process.stderr.write(`[question-review] create failed: ${res.status} ${text}
|
|
60377
|
+
`);
|
|
60378
|
+
return null;
|
|
60379
|
+
}
|
|
60380
|
+
return await res.json();
|
|
60381
|
+
} catch (error48) {
|
|
60382
|
+
process.stderr.write(`[question-review] create error: ${error48}
|
|
60383
|
+
`);
|
|
60384
|
+
return null;
|
|
60385
|
+
}
|
|
60386
|
+
}
|
|
60387
|
+
async function pollForAnswer(client, roomId, reviewId, pollInterval = POLL_INTERVAL_MS2, pollTimeout = POLL_TIMEOUT_MS2) {
|
|
60388
|
+
const deadline = Date.now() + pollTimeout;
|
|
60389
|
+
while (Date.now() < deadline) {
|
|
60390
|
+
try {
|
|
60391
|
+
const res = await client.api.rooms[":id"]["question-reviews"][":reviewId"].$get({
|
|
60392
|
+
param: { id: roomId, reviewId }
|
|
60393
|
+
});
|
|
60394
|
+
if (res.ok) {
|
|
60395
|
+
const data = await res.json();
|
|
60396
|
+
if (data.status !== "pending") {
|
|
60397
|
+
return data;
|
|
60398
|
+
}
|
|
60399
|
+
}
|
|
60400
|
+
} catch (error48) {
|
|
60401
|
+
process.stderr.write(`[question-review] poll error: ${error48}
|
|
60402
|
+
`);
|
|
60403
|
+
}
|
|
60404
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
60405
|
+
}
|
|
60406
|
+
return null;
|
|
60407
|
+
}
|
|
60408
|
+
function buildOutput(questions, answers) {
|
|
60409
|
+
return {
|
|
60410
|
+
hookSpecificOutput: {
|
|
60411
|
+
hookEventName: "PermissionRequest",
|
|
60412
|
+
decision: {
|
|
60413
|
+
behavior: "allow",
|
|
60414
|
+
updatedInput: {
|
|
60415
|
+
questions,
|
|
60416
|
+
answers
|
|
60417
|
+
}
|
|
60418
|
+
}
|
|
60419
|
+
}
|
|
60420
|
+
};
|
|
60421
|
+
}
|
|
60422
|
+
async function expireReview(client, roomId, reviewId) {
|
|
60423
|
+
try {
|
|
60424
|
+
await client.api.rooms[":id"]["question-reviews"][":reviewId"].expire.$post({
|
|
60425
|
+
param: { id: roomId, reviewId }
|
|
60426
|
+
});
|
|
60427
|
+
} catch {}
|
|
60428
|
+
}
|
|
60429
|
+
async function sendTimeoutMessage(client, roomId) {
|
|
60430
|
+
try {
|
|
60431
|
+
await client.api.rooms[":id"].messages.$post({
|
|
60432
|
+
param: { id: roomId },
|
|
60433
|
+
json: {
|
|
60434
|
+
sender: "hook",
|
|
60435
|
+
content: "_Question timed out — answer in terminal instead._",
|
|
60436
|
+
sender_type: "agent",
|
|
60437
|
+
color: "#f59e0b"
|
|
60438
|
+
}
|
|
60439
|
+
});
|
|
60440
|
+
} catch {}
|
|
60441
|
+
}
|
|
60442
|
+
async function processQuestionReview(rawInput, teamsDir, opts) {
|
|
60443
|
+
let input;
|
|
60444
|
+
try {
|
|
60445
|
+
input = JSON.parse(rawInput);
|
|
60446
|
+
} catch {
|
|
60447
|
+
process.stderr.write(`[question-review] failed to parse stdin
|
|
60448
|
+
`);
|
|
60449
|
+
return;
|
|
60450
|
+
}
|
|
60451
|
+
const { session_id: sessionId, hook_event_name: hookEventName, tool_input: toolInput } = input;
|
|
60452
|
+
if (!sessionId || !toolInput?.questions?.length) {
|
|
60453
|
+
process.stderr.write(`[question-review] missing session_id or questions
|
|
60454
|
+
`);
|
|
60455
|
+
return;
|
|
60456
|
+
}
|
|
60457
|
+
process.stderr.write(`[question-review] triggered by ${hookEventName} event
|
|
60458
|
+
`);
|
|
60459
|
+
const roomId = findRoomId(sessionId, teamsDir);
|
|
60460
|
+
if (!roomId) {
|
|
60461
|
+
process.stderr.write(`[question-review] no room found for session
|
|
60462
|
+
`);
|
|
60463
|
+
return;
|
|
60464
|
+
}
|
|
60465
|
+
const url2 = process.env.MEET_AI_URL;
|
|
60466
|
+
const key = process.env.MEET_AI_KEY;
|
|
60467
|
+
if (!url2 || !key) {
|
|
60468
|
+
process.stderr.write(`[question-review] MEET_AI_URL or MEET_AI_KEY not set
|
|
60469
|
+
`);
|
|
60470
|
+
return;
|
|
60471
|
+
}
|
|
60472
|
+
const client = createHookClient(url2, key);
|
|
60473
|
+
const formattedContent = formatQuestions(toolInput.questions);
|
|
60474
|
+
process.stderr.write(`[question-review] sending question to room ${roomId} via ${url2}
|
|
60475
|
+
`);
|
|
60476
|
+
const review = await createQuestionReview(client, roomId, toolInput.questions, formattedContent);
|
|
60477
|
+
if (!review)
|
|
60478
|
+
return;
|
|
60479
|
+
process.stderr.write(`[question-review] created: ${review.id}, polling for answer...
|
|
60480
|
+
`);
|
|
60481
|
+
const result = await pollForAnswer(client, roomId, review.id, opts?.pollInterval, opts?.pollTimeout);
|
|
60482
|
+
if (!result) {
|
|
60483
|
+
process.stderr.write(`[question-review] timed out waiting for answer
|
|
60484
|
+
`);
|
|
60485
|
+
await expireReview(client, roomId, review.id);
|
|
60486
|
+
await sendTimeoutMessage(client, roomId);
|
|
60487
|
+
return;
|
|
60488
|
+
}
|
|
60489
|
+
process.stderr.write(`[question-review] answer received: ${result.status}
|
|
60490
|
+
`);
|
|
60491
|
+
if (result.status === "answered" && result.answers_json) {
|
|
60492
|
+
let answers;
|
|
60493
|
+
try {
|
|
60494
|
+
answers = JSON.parse(result.answers_json);
|
|
60495
|
+
} catch (error48) {
|
|
60496
|
+
process.stderr.write(`[question-review] failed to parse answers_json: ${error48}
|
|
60497
|
+
`);
|
|
60498
|
+
return;
|
|
60499
|
+
}
|
|
60500
|
+
process.stdout.write(JSON.stringify(buildOutput(toolInput.questions, answers)));
|
|
60501
|
+
}
|
|
60502
|
+
}
|
|
60503
|
+
var POLL_INTERVAL_MS2 = 2000, POLL_TIMEOUT_MS2 = 1800000;
|
|
60504
|
+
var init_usecase13 = __esm(() => {
|
|
60505
|
+
init_client4();
|
|
60506
|
+
init_find_room();
|
|
60507
|
+
});
|
|
60508
|
+
|
|
60509
|
+
// src/commands/hook/question-review/command.ts
|
|
60510
|
+
var exports_command14 = {};
|
|
60511
|
+
__export(exports_command14, {
|
|
60512
|
+
default: () => command_default14
|
|
60513
|
+
});
|
|
60514
|
+
var command_default14;
|
|
60515
|
+
var init_command14 = __esm(() => {
|
|
60516
|
+
init_dist();
|
|
60517
|
+
init_usecase13();
|
|
60518
|
+
command_default14 = defineCommand({
|
|
60519
|
+
meta: {
|
|
60520
|
+
name: "question-review",
|
|
60521
|
+
description: "Handle Claude Code AskUser permission hook — routes questions to meet-ai room for review"
|
|
60522
|
+
},
|
|
60523
|
+
async run() {
|
|
60524
|
+
try {
|
|
60525
|
+
let input = "";
|
|
60526
|
+
for await (const chunk of process.stdin) {
|
|
60527
|
+
input += chunk;
|
|
60528
|
+
}
|
|
60529
|
+
await processQuestionReview(input);
|
|
60530
|
+
} catch (error48) {
|
|
60531
|
+
process.stderr.write(`[question-review] fatal: ${error48}
|
|
60532
|
+
`);
|
|
60533
|
+
}
|
|
60534
|
+
process.exit(0);
|
|
60535
|
+
}
|
|
60536
|
+
});
|
|
60537
|
+
});
|
|
60538
|
+
|
|
60539
|
+
// src/commands/hook/permission-review/usecase.ts
|
|
60540
|
+
function formatPermissionRequest(toolName, toolInput) {
|
|
60541
|
+
let text = `**Permission request: ${toolName}**
|
|
60542
|
+
`;
|
|
60543
|
+
if (toolInput) {
|
|
60544
|
+
const entries = Object.entries(toolInput);
|
|
60545
|
+
if (entries.length > 0) {
|
|
60546
|
+
for (const [key, value] of entries) {
|
|
60547
|
+
const valueStr = typeof value === "string" ? value : JSON.stringify(value);
|
|
60548
|
+
const truncated = valueStr.length > 200 ? valueStr.slice(0, 200) + "..." : valueStr;
|
|
60549
|
+
text += `
|
|
60550
|
+
**${key}:** \`${truncated}\``;
|
|
60551
|
+
}
|
|
60552
|
+
}
|
|
60553
|
+
}
|
|
60554
|
+
return text;
|
|
60555
|
+
}
|
|
60556
|
+
async function createPermissionReview(client, roomId, toolName, toolInput, formattedContent) {
|
|
60557
|
+
try {
|
|
60558
|
+
const res = await client.api.rooms[":id"]["permission-reviews"].$post({
|
|
60559
|
+
param: { id: roomId },
|
|
60560
|
+
json: {
|
|
60561
|
+
tool_name: toolName,
|
|
60562
|
+
tool_input_json: toolInput ? JSON.stringify(toolInput) : undefined,
|
|
60563
|
+
formatted_content: formattedContent
|
|
60564
|
+
}
|
|
60565
|
+
});
|
|
60566
|
+
if (!res.ok) {
|
|
60567
|
+
const text = await res.text();
|
|
60568
|
+
process.stderr.write(`[permission-review] create failed: ${res.status} ${text}
|
|
60569
|
+
`);
|
|
60570
|
+
return null;
|
|
60571
|
+
}
|
|
60572
|
+
return await res.json();
|
|
60573
|
+
} catch (error48) {
|
|
60574
|
+
process.stderr.write(`[permission-review] create error: ${error48}
|
|
60575
|
+
`);
|
|
60576
|
+
return null;
|
|
60577
|
+
}
|
|
60578
|
+
}
|
|
60579
|
+
async function pollForDecision2(client, roomId, reviewId, pollInterval = POLL_INTERVAL_MS3, pollTimeout = POLL_TIMEOUT_MS3) {
|
|
60580
|
+
const deadline = Date.now() + pollTimeout;
|
|
60581
|
+
while (Date.now() < deadline) {
|
|
60582
|
+
try {
|
|
60583
|
+
const res = await client.api.rooms[":id"]["permission-reviews"][":reviewId"].$get({
|
|
60584
|
+
param: { id: roomId, reviewId }
|
|
60585
|
+
});
|
|
60586
|
+
if (res.ok) {
|
|
60587
|
+
const data = await res.json();
|
|
60588
|
+
if (data.status !== "pending") {
|
|
60589
|
+
return data;
|
|
60590
|
+
}
|
|
60591
|
+
}
|
|
60592
|
+
} catch (error48) {
|
|
60593
|
+
process.stderr.write(`[permission-review] poll error: ${error48}
|
|
60594
|
+
`);
|
|
60595
|
+
}
|
|
60596
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
60597
|
+
}
|
|
60598
|
+
return null;
|
|
60599
|
+
}
|
|
60600
|
+
function buildAllowOutput2() {
|
|
60601
|
+
return {
|
|
60602
|
+
hookSpecificOutput: {
|
|
60603
|
+
hookEventName: "PermissionRequest",
|
|
60604
|
+
decision: { behavior: "allow" }
|
|
60605
|
+
}
|
|
60606
|
+
};
|
|
60607
|
+
}
|
|
60608
|
+
function buildDenyOutput2(message) {
|
|
60609
|
+
return {
|
|
60610
|
+
hookSpecificOutput: {
|
|
60611
|
+
hookEventName: "PermissionRequest",
|
|
60612
|
+
decision: {
|
|
60613
|
+
behavior: "deny",
|
|
60614
|
+
message
|
|
60615
|
+
}
|
|
60616
|
+
}
|
|
60617
|
+
};
|
|
60618
|
+
}
|
|
60619
|
+
async function expireReview2(client, roomId, reviewId) {
|
|
60620
|
+
try {
|
|
60621
|
+
await client.api.rooms[":id"]["permission-reviews"][":reviewId"].expire.$post({
|
|
60622
|
+
param: { id: roomId, reviewId }
|
|
60623
|
+
});
|
|
60624
|
+
} catch {}
|
|
60625
|
+
}
|
|
60626
|
+
async function sendTimeoutMessage2(client, roomId) {
|
|
60627
|
+
try {
|
|
60628
|
+
await client.api.rooms[":id"].messages.$post({
|
|
60629
|
+
param: { id: roomId },
|
|
60630
|
+
json: {
|
|
60631
|
+
sender: "hook",
|
|
60632
|
+
content: "_Permission request timed out — approve in terminal instead._",
|
|
60633
|
+
sender_type: "agent",
|
|
60634
|
+
color: "#f97316"
|
|
60635
|
+
}
|
|
60636
|
+
});
|
|
60637
|
+
} catch {}
|
|
60638
|
+
}
|
|
60639
|
+
async function processPermissionReview(rawInput, teamsDir, opts) {
|
|
60640
|
+
let input;
|
|
60641
|
+
try {
|
|
60642
|
+
input = JSON.parse(rawInput);
|
|
60643
|
+
} catch {
|
|
60644
|
+
process.stderr.write(`[permission-review] failed to parse stdin
|
|
60645
|
+
`);
|
|
60646
|
+
return;
|
|
60647
|
+
}
|
|
60648
|
+
const { session_id: sessionId, hook_event_name: hookEventName, tool_name: toolName, tool_input: toolInput } = input;
|
|
60649
|
+
if (!sessionId || !toolName) {
|
|
60650
|
+
process.stderr.write(`[permission-review] missing session_id or tool_name
|
|
60651
|
+
`);
|
|
60652
|
+
return;
|
|
60653
|
+
}
|
|
60654
|
+
const EXCLUDED_TOOLS = ["ExitPlanMode", "AskUserQuestion"];
|
|
60655
|
+
if (EXCLUDED_TOOLS.includes(toolName)) {
|
|
60656
|
+
process.stderr.write(`[permission-review] skipping ${toolName} — handled by dedicated hook
|
|
60657
|
+
`);
|
|
60658
|
+
return;
|
|
60659
|
+
}
|
|
60660
|
+
process.stderr.write(`[permission-review] triggered by ${hookEventName} for tool ${toolName}
|
|
60661
|
+
`);
|
|
60662
|
+
const roomId = findRoomId(sessionId, teamsDir);
|
|
60663
|
+
if (!roomId) {
|
|
60664
|
+
process.stderr.write(`[permission-review] no room found for session
|
|
60665
|
+
`);
|
|
60666
|
+
return;
|
|
60667
|
+
}
|
|
60668
|
+
const url2 = process.env.MEET_AI_URL;
|
|
60669
|
+
const key = process.env.MEET_AI_KEY;
|
|
60670
|
+
if (!url2 || !key) {
|
|
60671
|
+
process.stderr.write(`[permission-review] MEET_AI_URL or MEET_AI_KEY not set
|
|
60672
|
+
`);
|
|
60673
|
+
return;
|
|
60674
|
+
}
|
|
60675
|
+
const client = createHookClient(url2, key);
|
|
60676
|
+
const formattedContent = formatPermissionRequest(toolName, toolInput);
|
|
60677
|
+
process.stderr.write(`[permission-review] sending permission request to room ${roomId} via ${url2}
|
|
60678
|
+
`);
|
|
60679
|
+
const review = await createPermissionReview(client, roomId, toolName, toolInput, formattedContent);
|
|
60680
|
+
if (!review)
|
|
60681
|
+
return;
|
|
60682
|
+
process.stderr.write(`[permission-review] created: ${review.id}, polling for decision...
|
|
60683
|
+
`);
|
|
60684
|
+
const result = await pollForDecision2(client, roomId, review.id, opts?.pollInterval, opts?.pollTimeout);
|
|
60685
|
+
if (!result) {
|
|
60686
|
+
process.stderr.write(`[permission-review] timed out waiting for decision
|
|
60687
|
+
`);
|
|
60688
|
+
await expireReview2(client, roomId, review.id);
|
|
60689
|
+
await sendTimeoutMessage2(client, roomId);
|
|
60690
|
+
return;
|
|
60691
|
+
}
|
|
60692
|
+
process.stderr.write(`[permission-review] decision received: ${result.status}
|
|
60693
|
+
`);
|
|
60694
|
+
if (result.status === "approved") {
|
|
60695
|
+
process.stdout.write(JSON.stringify(buildAllowOutput2()));
|
|
60696
|
+
} else if (result.status === "denied") {
|
|
60697
|
+
const message = result.feedback || "Permission denied by user.";
|
|
60698
|
+
process.stdout.write(JSON.stringify(buildDenyOutput2(message)));
|
|
60699
|
+
}
|
|
60700
|
+
}
|
|
60701
|
+
var POLL_INTERVAL_MS3 = 2000, POLL_TIMEOUT_MS3 = 1800000;
|
|
60702
|
+
var init_usecase14 = __esm(() => {
|
|
60703
|
+
init_client4();
|
|
60704
|
+
init_find_room();
|
|
60705
|
+
});
|
|
60706
|
+
|
|
60707
|
+
// src/commands/hook/permission-review/command.ts
|
|
60708
|
+
var exports_command15 = {};
|
|
60709
|
+
__export(exports_command15, {
|
|
60710
|
+
default: () => command_default15
|
|
60711
|
+
});
|
|
60712
|
+
var command_default15;
|
|
60713
|
+
var init_command15 = __esm(() => {
|
|
60714
|
+
init_dist();
|
|
60715
|
+
init_usecase14();
|
|
60716
|
+
command_default15 = defineCommand({
|
|
60717
|
+
meta: {
|
|
60718
|
+
name: "permission-review",
|
|
60719
|
+
description: "Handle Claude Code PermissionRequest hook — routes tool permission requests to meet-ai room for review"
|
|
60720
|
+
},
|
|
60721
|
+
async run() {
|
|
60722
|
+
try {
|
|
60723
|
+
let input = "";
|
|
60724
|
+
for await (const chunk of process.stdin) {
|
|
60725
|
+
input += chunk;
|
|
60726
|
+
}
|
|
60727
|
+
await processPermissionReview(input);
|
|
60728
|
+
} catch (error48) {
|
|
60729
|
+
process.stderr.write(`[permission-review] fatal: ${error48}
|
|
60730
|
+
`);
|
|
60731
|
+
}
|
|
60732
|
+
process.exit(0);
|
|
60733
|
+
}
|
|
60734
|
+
});
|
|
60735
|
+
});
|
|
60736
|
+
|
|
60737
|
+
// src/commands/hook/command.ts
|
|
60738
|
+
var exports_command16 = {};
|
|
60739
|
+
__export(exports_command16, {
|
|
60740
|
+
default: () => command_default16
|
|
60741
|
+
});
|
|
60742
|
+
var command_default16;
|
|
60743
|
+
var init_command16 = __esm(() => {
|
|
60744
|
+
init_dist();
|
|
60745
|
+
command_default16 = defineCommand({
|
|
60746
|
+
meta: {
|
|
60747
|
+
name: "hook",
|
|
60748
|
+
description: "Claude Code hook subcommands"
|
|
60749
|
+
},
|
|
60750
|
+
subCommands: {
|
|
60751
|
+
"log-tool-use": () => Promise.resolve().then(() => (init_command12(), exports_command12)).then((m) => m.default),
|
|
60752
|
+
"plan-review": () => Promise.resolve().then(() => (init_command13(), exports_command13)).then((m) => m.default),
|
|
60753
|
+
"question-review": () => Promise.resolve().then(() => (init_command14(), exports_command14)).then((m) => m.default),
|
|
60754
|
+
"permission-review": () => Promise.resolve().then(() => (init_command15(), exports_command15)).then((m) => m.default)
|
|
60755
|
+
}
|
|
60756
|
+
});
|
|
60757
|
+
});
|
|
60758
|
+
|
|
60759
|
+
// src/commands/setup-hooks/usecase.ts
|
|
60760
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
60761
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
60762
|
+
import { resolve as resolve2, dirname as dirname2 } from "node:path";
|
|
60763
|
+
import { homedir as homedir3 } from "node:os";
|
|
60764
|
+
function isMeetAiHook(entry) {
|
|
60765
|
+
return entry.hooks?.some((h) => typeof h.command === "string" && h.command.startsWith("meet-ai hook ")) ?? false;
|
|
60766
|
+
}
|
|
60767
|
+
function getSettingsPath(project) {
|
|
60768
|
+
if (project) {
|
|
60769
|
+
return resolve2(process.cwd(), ".claude", "settings.json");
|
|
60770
|
+
}
|
|
60771
|
+
return resolve2(homedir3(), ".claude", "settings.json");
|
|
60772
|
+
}
|
|
60773
|
+
async function readSettings(path) {
|
|
60774
|
+
if (!existsSync4(path)) {
|
|
60775
|
+
return {};
|
|
60776
|
+
}
|
|
60777
|
+
const raw = await readFile(path, "utf-8");
|
|
60778
|
+
const trimmed = raw.trim();
|
|
60779
|
+
if (!trimmed)
|
|
60780
|
+
return {};
|
|
60781
|
+
try {
|
|
60782
|
+
return JSON.parse(trimmed);
|
|
60783
|
+
} catch {
|
|
60784
|
+
return {};
|
|
60785
|
+
}
|
|
60786
|
+
}
|
|
60787
|
+
function mergeHooks(existing) {
|
|
60788
|
+
const result = { ...existing };
|
|
60789
|
+
const added = [];
|
|
60790
|
+
for (const [event, matchers] of Object.entries(MEET_AI_HOOKS)) {
|
|
60791
|
+
if (!result[event]) {
|
|
60792
|
+
result[event] = [];
|
|
60793
|
+
}
|
|
60794
|
+
for (const newMatcher of matchers) {
|
|
60795
|
+
const existingIdx = result[event].findIndex((m) => m.matcher === newMatcher.matcher && isMeetAiHook(m));
|
|
60796
|
+
if (existingIdx >= 0) {
|
|
60797
|
+
result[event][existingIdx] = newMatcher;
|
|
60798
|
+
added.push(`updated ${event} [${newMatcher.matcher}]`);
|
|
60799
|
+
} else {
|
|
60800
|
+
result[event].push(newMatcher);
|
|
60801
|
+
added.push(`added ${event} [${newMatcher.matcher}]`);
|
|
60802
|
+
}
|
|
60803
|
+
}
|
|
60804
|
+
}
|
|
60805
|
+
return { merged: result, added };
|
|
60806
|
+
}
|
|
60807
|
+
function removeHooks(existing) {
|
|
60808
|
+
const result = {};
|
|
60809
|
+
const removed = [];
|
|
60810
|
+
for (const [event, matchers] of Object.entries(existing)) {
|
|
60811
|
+
const kept = matchers.filter((m) => {
|
|
60812
|
+
if (isMeetAiHook(m)) {
|
|
60813
|
+
removed.push(`removed ${event} [${m.matcher}]`);
|
|
60814
|
+
return false;
|
|
60815
|
+
}
|
|
60816
|
+
return true;
|
|
60817
|
+
});
|
|
60818
|
+
if (kept.length > 0) {
|
|
60819
|
+
result[event] = kept;
|
|
60820
|
+
}
|
|
60821
|
+
}
|
|
60822
|
+
return { cleaned: result, removed };
|
|
60823
|
+
}
|
|
60824
|
+
async function setupHooks(options) {
|
|
60825
|
+
const settingsPath = options._settingsPath ?? getSettingsPath(options.project);
|
|
60826
|
+
const settings = await readSettings(settingsPath);
|
|
60827
|
+
const existingHooks = settings.hooks ?? {};
|
|
60828
|
+
if (options.remove) {
|
|
60829
|
+
const { cleaned, removed } = removeHooks(existingHooks);
|
|
60830
|
+
if (removed.length === 0) {
|
|
60831
|
+
info("No meet-ai hooks found to remove.");
|
|
60832
|
+
return;
|
|
60833
|
+
}
|
|
60834
|
+
if (options.dryRun) {
|
|
60835
|
+
info(`Dry run — would modify ${settingsPath}:`);
|
|
60836
|
+
for (const r of removed) {
|
|
60837
|
+
console.log(import_picocolors2.default.yellow(` ${r}`));
|
|
60838
|
+
}
|
|
60839
|
+
return;
|
|
60840
|
+
}
|
|
60841
|
+
const updated = { ...settings, hooks: cleaned };
|
|
60842
|
+
if (Object.keys(cleaned).length === 0) {
|
|
60843
|
+
delete updated.hooks;
|
|
60844
|
+
}
|
|
60845
|
+
await mkdir(dirname2(settingsPath), { recursive: true });
|
|
60846
|
+
await writeFile(settingsPath, JSON.stringify(updated, null, 2) + `
|
|
60847
|
+
`);
|
|
60848
|
+
for (const r of removed) {
|
|
60849
|
+
console.log(import_picocolors2.default.yellow(` ${r}`));
|
|
60850
|
+
}
|
|
60851
|
+
ok(`Removed meet-ai hooks from ${settingsPath}`);
|
|
60852
|
+
} else {
|
|
60853
|
+
const { merged, added } = mergeHooks(existingHooks);
|
|
60854
|
+
if (options.dryRun) {
|
|
60855
|
+
info(`Dry run — would modify ${settingsPath}:`);
|
|
60856
|
+
for (const a of added) {
|
|
60857
|
+
console.log(import_picocolors2.default.green(` ${a}`));
|
|
60858
|
+
}
|
|
60859
|
+
return;
|
|
60860
|
+
}
|
|
60861
|
+
const updated = { ...settings, hooks: merged };
|
|
60862
|
+
await mkdir(dirname2(settingsPath), { recursive: true });
|
|
60863
|
+
await writeFile(settingsPath, JSON.stringify(updated, null, 2) + `
|
|
60864
|
+
`);
|
|
60865
|
+
for (const a of added) {
|
|
60866
|
+
console.log(import_picocolors2.default.green(` ${a}`));
|
|
60867
|
+
}
|
|
60868
|
+
ok(`Hooks written to ${settingsPath}`);
|
|
60869
|
+
}
|
|
60870
|
+
}
|
|
60871
|
+
var import_picocolors2, MEET_AI_HOOKS;
|
|
60872
|
+
var init_usecase15 = __esm(() => {
|
|
60873
|
+
init_output();
|
|
60874
|
+
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
60875
|
+
MEET_AI_HOOKS = {
|
|
60876
|
+
PostToolUse: [
|
|
60877
|
+
{
|
|
60878
|
+
matcher: ".*",
|
|
60879
|
+
hooks: [
|
|
60880
|
+
{
|
|
60881
|
+
type: "command",
|
|
60882
|
+
command: "meet-ai hook log-tool-use",
|
|
60883
|
+
timeout: 10
|
|
60884
|
+
}
|
|
60885
|
+
]
|
|
60886
|
+
}
|
|
60887
|
+
],
|
|
60888
|
+
PermissionRequest: [
|
|
60889
|
+
{
|
|
60890
|
+
matcher: "ExitPlanMode",
|
|
60891
|
+
hooks: [
|
|
60892
|
+
{
|
|
60893
|
+
type: "command",
|
|
60894
|
+
command: "meet-ai hook plan-review",
|
|
60895
|
+
timeout: 2592000
|
|
60896
|
+
}
|
|
60897
|
+
]
|
|
60898
|
+
},
|
|
60899
|
+
{
|
|
60900
|
+
matcher: "AskUserQuestion",
|
|
60901
|
+
hooks: [
|
|
60902
|
+
{
|
|
60903
|
+
type: "command",
|
|
60904
|
+
command: "meet-ai hook question-review",
|
|
60905
|
+
timeout: 1800
|
|
60906
|
+
}
|
|
60907
|
+
]
|
|
60908
|
+
},
|
|
60909
|
+
{
|
|
60910
|
+
matcher: ".*",
|
|
60911
|
+
hooks: [
|
|
60912
|
+
{
|
|
60913
|
+
type: "command",
|
|
60914
|
+
command: "meet-ai hook permission-review",
|
|
60915
|
+
timeout: 1800
|
|
60916
|
+
}
|
|
60917
|
+
]
|
|
60918
|
+
}
|
|
60919
|
+
]
|
|
60920
|
+
};
|
|
60921
|
+
});
|
|
60922
|
+
|
|
60923
|
+
// src/commands/setup-hooks/command.ts
|
|
60924
|
+
var exports_command17 = {};
|
|
60925
|
+
__export(exports_command17, {
|
|
60926
|
+
default: () => command_default17
|
|
60927
|
+
});
|
|
60928
|
+
var command_default17;
|
|
60929
|
+
var init_command17 = __esm(() => {
|
|
60930
|
+
init_dist();
|
|
60931
|
+
init_usecase15();
|
|
60932
|
+
init_output();
|
|
60933
|
+
command_default17 = defineCommand({
|
|
60934
|
+
meta: {
|
|
60935
|
+
name: "setup-hooks",
|
|
60936
|
+
description: "Configure Claude Code hooks for meet-ai in ~/.claude/settings.json"
|
|
60937
|
+
},
|
|
60938
|
+
args: {
|
|
60939
|
+
project: {
|
|
60940
|
+
type: "boolean",
|
|
60941
|
+
description: "Write to ./.claude/settings.json instead of ~/.claude/settings.json",
|
|
60942
|
+
default: false
|
|
60943
|
+
},
|
|
60944
|
+
"dry-run": {
|
|
60945
|
+
type: "boolean",
|
|
60946
|
+
description: "Print what would be written without actually writing",
|
|
60947
|
+
default: false
|
|
60948
|
+
},
|
|
60949
|
+
remove: {
|
|
60950
|
+
type: "boolean",
|
|
60951
|
+
description: "Remove meet-ai hooks from settings instead of adding them",
|
|
60952
|
+
default: false
|
|
60953
|
+
}
|
|
60954
|
+
},
|
|
60955
|
+
async run({ args }) {
|
|
60956
|
+
try {
|
|
60957
|
+
await setupHooks({
|
|
60958
|
+
project: args.project,
|
|
60959
|
+
dryRun: args["dry-run"],
|
|
60960
|
+
remove: args.remove
|
|
60961
|
+
});
|
|
60962
|
+
} catch (error48) {
|
|
60963
|
+
err(error48 instanceof Error ? error48.message : String(error48));
|
|
60964
|
+
process.exit(1);
|
|
60965
|
+
}
|
|
60966
|
+
}
|
|
60967
|
+
});
|
|
60968
|
+
});
|
|
60969
|
+
|
|
59655
60970
|
// src/index.ts
|
|
59656
60971
|
init_dist();
|
|
59657
60972
|
init_output();
|
|
59658
60973
|
var main = defineCommand({
|
|
59659
60974
|
meta: {
|
|
59660
60975
|
name: "meet-ai",
|
|
59661
|
-
version: "0.0.
|
|
60976
|
+
version: "0.0.19",
|
|
59662
60977
|
description: "CLI for meet-ai chat rooms — create rooms, send messages, and stream via WebSocket"
|
|
59663
60978
|
},
|
|
59664
60979
|
args: {
|
|
@@ -59679,7 +60994,9 @@ var main = defineCommand({
|
|
|
59679
60994
|
"send-tasks": () => Promise.resolve().then(() => (init_command8(), exports_command8)).then((m) => m.default),
|
|
59680
60995
|
"download-attachment": () => Promise.resolve().then(() => (init_command9(), exports_command9)).then((m) => m.default),
|
|
59681
60996
|
"generate-key": () => Promise.resolve().then(() => (init_command10(), exports_command10)).then((m) => m.default),
|
|
59682
|
-
dashboard: () => init_command11().then(() => exports_command11).then((m) => m.default)
|
|
60997
|
+
dashboard: () => init_command11().then(() => exports_command11).then((m) => m.default),
|
|
60998
|
+
hook: () => Promise.resolve().then(() => (init_command16(), exports_command16)).then((m) => m.default),
|
|
60999
|
+
"setup-hooks": () => Promise.resolve().then(() => (init_command17(), exports_command17)).then((m) => m.default)
|
|
59683
61000
|
},
|
|
59684
61001
|
async run({ args }) {
|
|
59685
61002
|
const hasSubcommand = process.argv.length > 2;
|