@fourier-labs/harbour-contracts 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contract-release.json +11 -11
- package/dist/gen-ts/contract-release.d.ts +6 -6
- package/dist/gen-ts/contract-release.js +6 -6
- package/dist/gen-ts/integration-execute-request.d.ts +1 -1
- package/dist/gen-ts/saas-connection.d.ts +4 -0
- package/gen-ts/contract-release.ts +6 -6
- package/gen-ts/integration-execute-request.ts +1 -1
- package/gen-ts/saas-connection.ts +4 -0
- package/package.json +1 -1
- package/schema/integration-execute-request.schema.json +1 -1
- package/schema/saas-connection.schema.json +3 -2
package/contract-release.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "harbour.contract-release/1.0",
|
|
3
|
-
"repositoryVersion": "0.
|
|
4
|
-
"publishVersion": "0.
|
|
5
|
-
"publishTag": "v0.
|
|
6
|
-
"schemasDigest": "sha256:
|
|
3
|
+
"repositoryVersion": "0.54.0.0",
|
|
4
|
+
"publishVersion": "0.54.0",
|
|
5
|
+
"publishTag": "v0.54.0",
|
|
6
|
+
"schemasDigest": "sha256:fc7bd2680afba97f97aa634ea1d75d93acb608268e507b36f225bcdd29d14d62",
|
|
7
7
|
"aiFixturesDigest": "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6",
|
|
8
|
-
"generatedGoDigest": "sha256:
|
|
9
|
-
"generatedTypeScriptDigest": "sha256:
|
|
8
|
+
"generatedGoDigest": "sha256:4a5ac1dfae12d5dab89db517aacf83ffb499b88140f56b428a05dd4a522f9a9e",
|
|
9
|
+
"generatedTypeScriptDigest": "sha256:b6dd57fd1527d211f7ab9efbf374058251e21dade6bfdb0122053c720a1016cc",
|
|
10
10
|
"generatedExclusions": {
|
|
11
11
|
"gen-go/contract_release.go": "contains the generated aggregate digests (self-reference)",
|
|
12
12
|
"gen-ts/contract-release.ts": "contains the generated aggregate digests (self-reference)"
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
"schema/error-envelope.schema.json": "sha256:75dccda7dd16fdf8435deda53fc7dbcdc109b65114617a17f11763010c656f90",
|
|
53
53
|
"schema/integration-connect-result.schema.json": "sha256:3f254b67ef739dc1fa395bdc8c4dc93359b16d481dba2a2d777aa5b6f34b7af8",
|
|
54
54
|
"schema/integration-error-details.schema.json": "sha256:09cebaddb7f88e63cbebaa1cada5f91057ae4dc4370e973ef38f7f11c6323284",
|
|
55
|
-
"schema/integration-execute-request.schema.json": "sha256:
|
|
55
|
+
"schema/integration-execute-request.schema.json": "sha256:af2b60a623f397bbd82f825e67baaf07f0c67e74c812245a58bb3e87d8204c8e",
|
|
56
56
|
"schema/integration-execute-result.schema.json": "sha256:766146779c01ee1dbdd2161c5dc594f43ccaf322762352bb0dc5b80bcb3275b5",
|
|
57
57
|
"schema/kit-bundle-manifest.schema.json": "sha256:c15e28ae028dbd1c262427b9c797142e19b1f38fa36b4ecfe187e32c20a174ec",
|
|
58
58
|
"schema/kit-lock.schema.json": "sha256:5e24b76660f83990af7a6c037af350c3850ee439ef956f65a0360facbdcdd997",
|
|
59
59
|
"schema/kvs-routing-entry.schema.json": "sha256:b75f3a5dfa93a428b2764e03222b66b6ef2bed980f8bac8ffac54afdf3526bc5",
|
|
60
60
|
"schema/promotion-request.schema.json": "sha256:00e96dfd8ddbdba88ea222941d43f3609ff6c815a79e34f6705cab458101c969",
|
|
61
61
|
"schema/promotion-response.schema.json": "sha256:4129712d2e29d6ef21d93d4bd0bacfd60ada3f2ee0ade852824e64346b817634",
|
|
62
|
-
"schema/saas-connection.schema.json": "sha256:
|
|
62
|
+
"schema/saas-connection.schema.json": "sha256:82ed8018201800a95aa792bde1d22568e86b55b3be926aa094a260c8c78a58d7",
|
|
63
63
|
"schema/sanitized-binding-evidence.schema.json": "sha256:1191ab88e2764df927e5f17837674cebebe068d480da2b2fdb390e589f96b51f",
|
|
64
64
|
"schema/secret-reference.schema.json": "sha256:db4e3c2c6a2dbd72d7ea0f9c91cb3b2343a7e67b601996c6818b2ef08e440895",
|
|
65
65
|
"schema/security-scan-input.schema.json": "sha256:83502dffb3c07ac2e0698928e6dc123f454fc667d4aacd336bcad6944ef2ac3d",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"gen-go/integration_execute_input_rules.go": "sha256:224fb490a5f936b30927e6637e698093e1e42a695cbc1bcf9a39bc70db9f2172",
|
|
109
109
|
"gen-go/integration_execute_input_rules_test.go": "sha256:c437a8406a2f062a0173b9419e4cb176fc6eb54e569506225d5162323f55b40b",
|
|
110
110
|
"gen-go/schema_documents.go": "sha256:a01b157658d23e2585e64ff101ed720942856626676b50c83efbd8b044a050d6",
|
|
111
|
-
"gen-go/types.go": "sha256:
|
|
111
|
+
"gen-go/types.go": "sha256:7b764054cd42765ca9532133f0b5f83c0ca4bd7af78ea7bfa7ab4f8ba407891c",
|
|
112
112
|
"gen-go/version_state.go": "sha256:4ef8abb126414c0025cf2c59bc9c79a74ef4a2ff89e8f316cbf05acc872371c1"
|
|
113
113
|
},
|
|
114
114
|
"generatedTypeScript": {
|
|
@@ -158,14 +158,14 @@
|
|
|
158
158
|
"gen-ts/integration-connect-result.ts": "sha256:4b10f169b6e1af364e9b418de21caa9fadbfb77b43cbff77d741cfae0b52180c",
|
|
159
159
|
"gen-ts/integration-error-details.ts": "sha256:8243f5871f376d1cab4d90e07f3151d148fb03c704168dbccdfe6c9fe76bce83",
|
|
160
160
|
"gen-ts/integration-execute-input-rules.ts": "sha256:a779c872c44bb892dec7b28173d961696d95e5b6e1fa14e2ba67dd78344cdc5b",
|
|
161
|
-
"gen-ts/integration-execute-request.ts": "sha256:
|
|
161
|
+
"gen-ts/integration-execute-request.ts": "sha256:7fe65e3534544eb6d2a1e7d4813fc1d89c69c148f7ca74ad493a17a7cea6b796",
|
|
162
162
|
"gen-ts/integration-execute-result.ts": "sha256:4aaf6a9688f9dfdbc87a408556b62f822518acf5b76548076adb55393c0863b4",
|
|
163
163
|
"gen-ts/kit-bundle-manifest.ts": "sha256:9041b32af3df781ca6800bc14c3719e5e54c81dff370633454ac3ad27432eb58",
|
|
164
164
|
"gen-ts/kit-lock.ts": "sha256:de4ae82bac7bd234a3230ae671962e80eed6542d695a032a442673659dc6be5e",
|
|
165
165
|
"gen-ts/kvs-routing-entry.ts": "sha256:d92e85ee9f257d77850d1d3aac9438e2055f38084ff84a48fcedae239d47d4ca",
|
|
166
166
|
"gen-ts/promotion-request.ts": "sha256:9db88cef67f777a16bac628039ec3f582acb9e8cfff6fb592b30d0a0e55abc68",
|
|
167
167
|
"gen-ts/promotion-response.ts": "sha256:f1c9cafac96faeb02a443a31786f67714e818f38d90108e7af41958396524d6f",
|
|
168
|
-
"gen-ts/saas-connection.ts": "sha256:
|
|
168
|
+
"gen-ts/saas-connection.ts": "sha256:a4b7a9b37db0cf747ca1c40db5b1459ade2a86cc067146154c3c42484b76e07a",
|
|
169
169
|
"gen-ts/sanitized-binding-digest-helper.ts": "sha256:c47d7fdc20500e2e72c23fe39ecdd610fc397c47fcba51335ebec3c380fe6872",
|
|
170
170
|
"gen-ts/sanitized-binding-evidence.ts": "sha256:f3fb7b1d7d2e0929eb0ea981eaf32db3104010647185f6ae59f67167d42538a9",
|
|
171
171
|
"gen-ts/secret-reference.ts": "sha256:731fbcde7315cb4128d5b01bdbe6e6f248f13c7ad8dea04a3a4e927ac4890198",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export declare const ContractRepositoryVersion: "0.
|
|
2
|
-
export declare const ContractPublishVersion: "0.
|
|
3
|
-
export declare const ContractPublishTag: "v0.
|
|
4
|
-
export declare const ContractSchemasDigest: "sha256:
|
|
1
|
+
export declare const ContractRepositoryVersion: "0.54.0.0";
|
|
2
|
+
export declare const ContractPublishVersion: "0.54.0";
|
|
3
|
+
export declare const ContractPublishTag: "v0.54.0";
|
|
4
|
+
export declare const ContractSchemasDigest: "sha256:fc7bd2680afba97f97aa634ea1d75d93acb608268e507b36f225bcdd29d14d62";
|
|
5
5
|
export declare const ContractAiFixturesDigest: "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
|
|
6
|
-
export declare const ContractGeneratedGoDigest: "sha256:
|
|
7
|
-
export declare const ContractGeneratedTypeScriptDigest: "sha256:
|
|
6
|
+
export declare const ContractGeneratedGoDigest: "sha256:4a5ac1dfae12d5dab89db517aacf83ffb499b88140f56b428a05dd4a522f9a9e";
|
|
7
|
+
export declare const ContractGeneratedTypeScriptDigest: "sha256:b6dd57fd1527d211f7ab9efbf374058251e21dade6bfdb0122053c720a1016cc";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
|
-
export const ContractRepositoryVersion = "0.
|
|
4
|
-
export const ContractPublishVersion = "0.
|
|
5
|
-
export const ContractPublishTag = "v0.
|
|
6
|
-
export const ContractSchemasDigest = "sha256:
|
|
3
|
+
export const ContractRepositoryVersion = "0.54.0.0";
|
|
4
|
+
export const ContractPublishVersion = "0.54.0";
|
|
5
|
+
export const ContractPublishTag = "v0.54.0";
|
|
6
|
+
export const ContractSchemasDigest = "sha256:fc7bd2680afba97f97aa634ea1d75d93acb608268e507b36f225bcdd29d14d62";
|
|
7
7
|
export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
|
|
8
|
-
export const ContractGeneratedGoDigest = "sha256:
|
|
9
|
-
export const ContractGeneratedTypeScriptDigest = "sha256:
|
|
8
|
+
export const ContractGeneratedGoDigest = "sha256:4a5ac1dfae12d5dab89db517aacf83ffb499b88140f56b428a05dd4a522f9a9e";
|
|
9
|
+
export const ContractGeneratedTypeScriptDigest = "sha256:b6dd57fd1527d211f7ab9efbf374058251e21dade6bfdb0122053c720a1016cc";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a "Posted by <app> on
|
|
2
|
+
* Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a "Posted by <app> on Isomorph" footer) or as the signed-in person (no name, no footer), whichever mode the app declared and IT approved — the same input either way. Per-operation input bounds: slack.channel.history {limit? 1..15, default 15}; slack.message.post {text 1..4000 chars} and a required idempotencyKey retained across retries of one explicit Send; gmail.thread.list {limit? 1..15, default 15}; gmail.message.read {messageId}; gmail.message.send {to 1..50 addresses (to+cc+bcc <= 50 in total), cc?, bcc?, subject 1..256 chars, text 1..4000 chars, replyToMessageId?} and a required idempotencyKey like slack.message.post (plain text only, no attachments); warehouse.view.read {columns 1..32, limit? 1..1000, default 100}. Each operation's then-block is the one statement of its input rules: propertyNames.enum names the fields it accepts, required the ones it needs, and per-field overrides (maximum, default) narrow the shared property. Codegen derives IntegrationExecuteInputRules and validateIntegrationExecuteInput (gen-ts/integration-execute-input-rules.ts, gen-go/integration_execute_input_rules.go) from exactly these blocks, so the governance execute route, the app SDK and the kit's local check refuse the same request with the same message. Transport limits (not expressible here): request <= 16 KiB, total deadline 10 s.
|
|
3
3
|
*/
|
|
4
4
|
export type IntegrationExecuteRequest = {
|
|
5
5
|
/**
|
|
@@ -99,6 +99,10 @@ export interface SaasInstallation {
|
|
|
99
99
|
* @maxItems 64
|
|
100
100
|
*/
|
|
101
101
|
scopes?: string[];
|
|
102
|
+
/**
|
|
103
|
+
* The installed bot user's Slack username as auth.test reported it at installation (0.54.0), e.g. `isomorph_ai` — what a person types after /invite. Absent on installations recorded before it.
|
|
104
|
+
*/
|
|
105
|
+
botName?: string;
|
|
102
106
|
}
|
|
103
107
|
export interface DevelopmentPreapproval {
|
|
104
108
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
3
|
|
|
4
|
-
export const ContractRepositoryVersion = "0.
|
|
5
|
-
export const ContractPublishVersion = "0.
|
|
6
|
-
export const ContractPublishTag = "v0.
|
|
7
|
-
export const ContractSchemasDigest = "sha256:
|
|
4
|
+
export const ContractRepositoryVersion = "0.54.0.0" as const;
|
|
5
|
+
export const ContractPublishVersion = "0.54.0" as const;
|
|
6
|
+
export const ContractPublishTag = "v0.54.0" as const;
|
|
7
|
+
export const ContractSchemasDigest = "sha256:fc7bd2680afba97f97aa634ea1d75d93acb608268e507b36f225bcdd29d14d62" as const;
|
|
8
8
|
export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6" as const;
|
|
9
|
-
export const ContractGeneratedGoDigest = "sha256:
|
|
10
|
-
export const ContractGeneratedTypeScriptDigest = "sha256:
|
|
9
|
+
export const ContractGeneratedGoDigest = "sha256:4a5ac1dfae12d5dab89db517aacf83ffb499b88140f56b428a05dd4a522f9a9e" as const;
|
|
10
|
+
export const ContractGeneratedTypeScriptDigest = "sha256:b6dd57fd1527d211f7ab9efbf374058251e21dade6bfdb0122053c720a1016cc" as const;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a "Posted by <app> on
|
|
5
|
+
* Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a "Posted by <app> on Isomorph" footer) or as the signed-in person (no name, no footer), whichever mode the app declared and IT approved — the same input either way. Per-operation input bounds: slack.channel.history {limit? 1..15, default 15}; slack.message.post {text 1..4000 chars} and a required idempotencyKey retained across retries of one explicit Send; gmail.thread.list {limit? 1..15, default 15}; gmail.message.read {messageId}; gmail.message.send {to 1..50 addresses (to+cc+bcc <= 50 in total), cc?, bcc?, subject 1..256 chars, text 1..4000 chars, replyToMessageId?} and a required idempotencyKey like slack.message.post (plain text only, no attachments); warehouse.view.read {columns 1..32, limit? 1..1000, default 100}. Each operation's then-block is the one statement of its input rules: propertyNames.enum names the fields it accepts, required the ones it needs, and per-field overrides (maximum, default) narrow the shared property. Codegen derives IntegrationExecuteInputRules and validateIntegrationExecuteInput (gen-ts/integration-execute-input-rules.ts, gen-go/integration_execute_input_rules.go) from exactly these blocks, so the governance execute route, the app SDK and the kit's local check refuse the same request with the same message. Transport limits (not expressible here): request <= 16 KiB, total deadline 10 s.
|
|
6
6
|
*/
|
|
7
7
|
export type IntegrationExecuteRequest = {
|
|
8
8
|
/**
|
|
@@ -110,6 +110,10 @@ export interface SaasInstallation {
|
|
|
110
110
|
* @maxItems 64
|
|
111
111
|
*/
|
|
112
112
|
scopes?: string[];
|
|
113
|
+
/**
|
|
114
|
+
* The installed bot user's Slack username as auth.test reported it at installation (0.54.0), e.g. `isomorph_ai` — what a person types after /invite. Absent on installations recorded before it.
|
|
115
|
+
*/
|
|
116
|
+
botName?: string;
|
|
113
117
|
}
|
|
114
118
|
export interface DevelopmentPreapproval {
|
|
115
119
|
/**
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://schemas.harbour.dev/integration-execute-request.schema.json",
|
|
4
4
|
"title": "IntegrationExecuteRequest",
|
|
5
|
-
"description": "Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a \"Posted by <app> on
|
|
5
|
+
"description": "Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is NOT a caller field: it is fixed by the operation (declared per app for slack.message.post) and enforced from the approved grant; any identity/userId/scope field is rejected by additionalProperties. A slack.message.post runs as the app (the IT-approved per-app name from the grant, plus a \"Posted by <app> on Isomorph\" footer) or as the signed-in person (no name, no footer), whichever mode the app declared and IT approved — the same input either way. Per-operation input bounds: slack.channel.history {limit? 1..15, default 15}; slack.message.post {text 1..4000 chars} and a required idempotencyKey retained across retries of one explicit Send; gmail.thread.list {limit? 1..15, default 15}; gmail.message.read {messageId}; gmail.message.send {to 1..50 addresses (to+cc+bcc <= 50 in total), cc?, bcc?, subject 1..256 chars, text 1..4000 chars, replyToMessageId?} and a required idempotencyKey like slack.message.post (plain text only, no attachments); warehouse.view.read {columns 1..32, limit? 1..1000, default 100}. Each operation's then-block is the one statement of its input rules: propertyNames.enum names the fields it accepts, required the ones it needs, and per-field overrides (maximum, default) narrow the shared property. Codegen derives IntegrationExecuteInputRules and validateIntegrationExecuteInput (gen-ts/integration-execute-input-rules.ts, gen-go/integration_execute_input_rules.go) from exactly these blocks, so the governance execute route, the app SDK and the kit's local check refuse the same request with the same message. Transport limits (not expressible here): request <= 16 KiB, total deadline 10 s.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["connection", "operation", "resource", "input"],
|
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
"botUserId": { "type": "string", "maxLength": 128, "description": "Empty only for a legacy record normalised without one." },
|
|
96
96
|
"status": { "$ref": "#/definitions/SaasInstallationStatus" },
|
|
97
97
|
"installedAt": { "type": "string", "format": "date-time" },
|
|
98
|
-
"scopes": { "type": "array", "maxItems": 64, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 64 }, "description": "The bot scopes Slack granted at installation (0.53.0). Absent on installations recorded before it, which therefore lack chat:write.customize: per-app display names need a reinstall." }
|
|
98
|
+
"scopes": { "type": "array", "maxItems": 64, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 64 }, "description": "The bot scopes Slack granted at installation (0.53.0). Absent on installations recorded before it, which therefore lack chat:write.customize: per-app display names need a reinstall." },
|
|
99
|
+
"botName": { "type": "string", "minLength": 1, "maxLength": 128, "description": "The installed bot user's Slack username as auth.test reported it at installation (0.54.0), e.g. `isomorph_ai` — what a person types after /invite. Absent on installations recorded before it." }
|
|
99
100
|
}
|
|
100
101
|
},
|
|
101
102
|
"DevelopmentPreapproval": {
|
|
@@ -145,7 +146,7 @@
|
|
|
145
146
|
"displayName": "Company Slack",
|
|
146
147
|
"status": "ACTIVE",
|
|
147
148
|
"version": 3,
|
|
148
|
-
"installation": { "tokenRecordId": "tok_workspace", "workspaceId": "T0WORKSPACE", "botUserId": "U0BOT", "status": "installed", "installedAt": "2026-09-09T08:00:00Z", "scopes": ["channels:read", "chat:write", "chat:write.customize"] },
|
|
149
|
+
"installation": { "tokenRecordId": "tok_workspace", "workspaceId": "T0WORKSPACE", "botUserId": "U0BOT", "status": "installed", "installedAt": "2026-09-09T08:00:00Z", "scopes": ["channels:read", "chat:write", "chat:write.customize"], "botName": "isomorph_ai" },
|
|
149
150
|
"channels": { "team-updates": "C0123TEAM" },
|
|
150
151
|
"operations": ["slack.channel.history", "slack.message.post"],
|
|
151
152
|
"developmentPreapproval": { "enabled": true, "hours": 24 },
|