@kansodata/kansodata-glue-plugin 0.1.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/AGENTS.md +30 -0
- package/README.md +119 -0
- package/dist/client/glueClientFactory.d.ts +3 -0
- package/dist/client/glueClientFactory.js +7 -0
- package/dist/client/glueClientFactory.js.map +1 -0
- package/dist/config/loadConfig.d.ts +7 -0
- package/dist/config/loadConfig.js +82 -0
- package/dist/config/loadConfig.js.map +1 -0
- package/dist/config/schema.d.ts +110 -0
- package/dist/config/schema.js +78 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/domain/contracts.d.ts +65 -0
- package/dist/domain/contracts.js +2 -0
- package/dist/domain/contracts.js.map +1 -0
- package/dist/errors/glueErrors.d.ts +30 -0
- package/dist/errors/glueErrors.js +43 -0
- package/dist/errors/glueErrors.js.map +1 -0
- package/dist/guards/operationGuards.d.ts +4 -0
- package/dist/guards/operationGuards.js +28 -0
- package/dist/guards/operationGuards.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +14 -0
- package/dist/manifest.js +15 -0
- package/dist/manifest.js.map +1 -0
- package/dist/openclawEntry.d.ts +8 -0
- package/dist/openclawEntry.js +41 -0
- package/dist/openclawEntry.js.map +1 -0
- package/dist/pluginMetadata.d.ts +5 -0
- package/dist/pluginMetadata.js +6 -0
- package/dist/pluginMetadata.js.map +1 -0
- package/dist/runtime/pluginRuntime.d.ts +22 -0
- package/dist/runtime/pluginRuntime.js +47 -0
- package/dist/runtime/pluginRuntime.js.map +1 -0
- package/dist/services/glueService.d.ts +79 -0
- package/dist/services/glueService.js +318 -0
- package/dist/services/glueService.js.map +1 -0
- package/dist/tools/catalog/catalogTools.d.ts +6 -0
- package/dist/tools/catalog/catalogTools.js +108 -0
- package/dist/tools/catalog/catalogTools.js.map +1 -0
- package/dist/tools/common.d.ts +4 -0
- package/dist/tools/common.js +19 -0
- package/dist/tools/common.js.map +1 -0
- package/dist/tools/registry.d.ts +3 -0
- package/dist/tools/registry.js +6 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/triggers/triggerTools.d.ts +6 -0
- package/dist/tools/triggers/triggerTools.js +157 -0
- package/dist/tools/triggers/triggerTools.js.map +1 -0
- package/dist/tools/workflows/workflowTools.d.ts +6 -0
- package/dist/tools/workflows/workflowTools.js +106 -0
- package/dist/tools/workflows/workflowTools.js.map +1 -0
- package/dist/utils/sanitize.d.ts +4 -0
- package/dist/utils/sanitize.js +34 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/docs/architecture.md +33 -0
- package/docs/roadmap.md +23 -0
- package/docs/rollback.md +34 -0
- package/docs/threat-model.md +31 -0
- package/docs/usage.md +70 -0
- package/openclaw.plugin.json +73 -0
- package/package.json +57 -0
- package/skills/kansodata-glue-operator/SKILL.md +47 -0
- package/skills/kansodata-glue-operator/docs/examples.md +44 -0
- package/skills/kansodata-glue-operator/docs/scope.md +37 -0
package/docs/usage.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Usage
|
|
2
|
+
|
|
3
|
+
## Runtime Initialization
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createPluginRuntime } from "@kansodata/kansodata-glue-plugin";
|
|
7
|
+
|
|
8
|
+
const runtime = createPluginRuntime();
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## OpenClaw Plugin Loading
|
|
12
|
+
|
|
13
|
+
- Manifest: `openclaw.plugin.json`
|
|
14
|
+
- Runtime extension entry: `package.json -> openclaw.extensions -> ./dist/openclawEntry.js`
|
|
15
|
+
- Companion skill discovery: `openclaw.plugin.json -> skills -> ["./skills"]`
|
|
16
|
+
- Runtime config precedence: `OpenClaw pluginConfig -> env vars -> schema defaults`
|
|
17
|
+
|
|
18
|
+
## Runtime Config Mapping
|
|
19
|
+
|
|
20
|
+
- `region` -> fallback `AWS_REGION` / `AWS_DEFAULT_REGION`
|
|
21
|
+
- `profile` -> fallback `AWS_PROFILE`
|
|
22
|
+
- `endpointOverride` -> fallback `KANSODATA_GLUE_ENDPOINT_OVERRIDE`
|
|
23
|
+
- `allowedNamePrefixes` -> fallback `KANSODATA_GLUE_ALLOWED_PREFIXES`
|
|
24
|
+
- `enforcePrefixAllowlist` -> fallback `KANSODATA_GLUE_ENFORCE_PREFIX_ALLOWLIST`
|
|
25
|
+
- `dryRunByDefault` -> fallback `KANSODATA_GLUE_DRY_RUN_BY_DEFAULT`
|
|
26
|
+
- `maxPartitionSampleSize` -> fallback `KANSODATA_GLUE_MAX_PARTITION_SAMPLE_SIZE`
|
|
27
|
+
|
|
28
|
+
## Read Examples
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
await runtime.executeTool("glue_get_workflow", { name: "kdo-sales-wf" });
|
|
32
|
+
await runtime.executeTool("glue_list_catalog_tables", {
|
|
33
|
+
databaseName: "analytics",
|
|
34
|
+
maxResults: 20
|
|
35
|
+
});
|
|
36
|
+
await runtime.executeTool("glue_explain_partitioning", {
|
|
37
|
+
databaseName: "analytics",
|
|
38
|
+
tableName: "fact_orders",
|
|
39
|
+
sampleSize: 10
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Controlled Write Examples
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
await runtime.executeTool("glue_create_workflow", {
|
|
47
|
+
name: "kdo-sales-wf",
|
|
48
|
+
description: "Sales workflow",
|
|
49
|
+
dryRun: true
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await runtime.executeTool("glue_update_trigger", {
|
|
53
|
+
name: "kdo-sales-schedule",
|
|
54
|
+
schedule: "cron(0 2 * * ? *)",
|
|
55
|
+
dryRun: true
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`glue_update_trigger` mutable fields are intentionally limited to:
|
|
60
|
+
- `schedule`
|
|
61
|
+
- `description`
|
|
62
|
+
- `actions`
|
|
63
|
+
- `predicate`
|
|
64
|
+
|
|
65
|
+
## Recommended Operator Sequence
|
|
66
|
+
1. Read current state (`get/list`).
|
|
67
|
+
2. Build expected impact summary.
|
|
68
|
+
3. Validate names, scope, and dry-run result.
|
|
69
|
+
4. Apply with explicit `dryRun: false` only when safe.
|
|
70
|
+
5. Verify resulting state with `get`.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "kansodata-glue",
|
|
3
|
+
"name": "@kansodata/kansodata-glue-plugin",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Controlled AWS Glue workflow/trigger writes and catalog diagnostics for ETL operator agents.",
|
|
6
|
+
"skills": [
|
|
7
|
+
"./skills"
|
|
8
|
+
],
|
|
9
|
+
"configSchema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"properties": {
|
|
13
|
+
"region": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"description": "AWS region for Glue operations. Fallback: AWS_REGION/AWS_DEFAULT_REGION."
|
|
17
|
+
},
|
|
18
|
+
"profile": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"minLength": 1,
|
|
21
|
+
"description": "Optional AWS profile. Fallback: AWS_PROFILE."
|
|
22
|
+
},
|
|
23
|
+
"endpointOverride": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"format": "uri",
|
|
26
|
+
"minLength": 1,
|
|
27
|
+
"description": "Optional Glue endpoint override (strict URL validation)."
|
|
28
|
+
},
|
|
29
|
+
"allowedNamePrefixes": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"minLength": 1
|
|
34
|
+
},
|
|
35
|
+
"default": [],
|
|
36
|
+
"description": "Allowed resource name prefixes for write operations."
|
|
37
|
+
},
|
|
38
|
+
"enforcePrefixAllowlist": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"default": true,
|
|
41
|
+
"description": "When true, writes are rejected outside allowed prefixes."
|
|
42
|
+
},
|
|
43
|
+
"dryRunByDefault": {
|
|
44
|
+
"type": "boolean",
|
|
45
|
+
"default": true,
|
|
46
|
+
"description": "Default write mode. True keeps writes in dry-run unless overridden."
|
|
47
|
+
},
|
|
48
|
+
"maxPartitionSampleSize": {
|
|
49
|
+
"type": "integer",
|
|
50
|
+
"minimum": 1,
|
|
51
|
+
"maximum": 25,
|
|
52
|
+
"default": 10,
|
|
53
|
+
"description": "Upper bound for partition diagnostics sample size."
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"contracts": {
|
|
58
|
+
"tools": [
|
|
59
|
+
"glue_list_workflows",
|
|
60
|
+
"glue_get_workflow",
|
|
61
|
+
"glue_create_workflow",
|
|
62
|
+
"glue_update_workflow",
|
|
63
|
+
"glue_list_triggers",
|
|
64
|
+
"glue_get_trigger",
|
|
65
|
+
"glue_create_trigger",
|
|
66
|
+
"glue_update_trigger",
|
|
67
|
+
"glue_get_catalog_table",
|
|
68
|
+
"glue_list_catalog_tables",
|
|
69
|
+
"glue_get_catalog_partitions_sample",
|
|
70
|
+
"glue_explain_partitioning"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kansodata/kansodata-glue-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenClaw plugin and companion skill for controlled AWS Glue orchestration writes and ETL catalog diagnostics.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"openclaw.plugin.json",
|
|
11
|
+
"skills",
|
|
12
|
+
"docs",
|
|
13
|
+
"README.md",
|
|
14
|
+
"AGENTS.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"clean": "node -e \"const { rmSync } = require('node:fs'); rmSync('dist', { recursive: true, force: true });\"",
|
|
18
|
+
"build": "npm run clean && tsc -p tsconfig.json",
|
|
19
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
20
|
+
"lint": "eslint .",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"validate": "npm run lint && npm run typecheck && npm run build && npm run test"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"openclaw",
|
|
26
|
+
"aws-glue",
|
|
27
|
+
"plugin",
|
|
28
|
+
"etl"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.14.0"
|
|
33
|
+
},
|
|
34
|
+
"openclaw": {
|
|
35
|
+
"extensions": [
|
|
36
|
+
"./dist/openclawEntry.js"
|
|
37
|
+
],
|
|
38
|
+
"compat": {
|
|
39
|
+
"pluginApi": ">=2026.4.14",
|
|
40
|
+
"minGatewayVersion": "2026.4.14"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@sinclair/typebox": "^0.34.41",
|
|
45
|
+
"@aws-sdk/client-glue": "^3.917.0",
|
|
46
|
+
"openclaw": "^2026.4.14",
|
|
47
|
+
"zod": "^3.24.1"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.14.1",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.31.0",
|
|
52
|
+
"@typescript-eslint/parser": "^8.31.0",
|
|
53
|
+
"eslint": "^9.24.0",
|
|
54
|
+
"typescript": "^5.8.3",
|
|
55
|
+
"vitest": "^3.1.1"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Skill: kansodata-glue-operator
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Operational companion for the `@kansodata/kansodata-glue-plugin` OpenClaw plugin. It governs safe sequencing and rejection criteria for AWS Glue orchestration changes and ETL catalog diagnostics.
|
|
5
|
+
|
|
6
|
+
## Operational Modes
|
|
7
|
+
- `diagnose`: read-only ETL/catalog diagnosis.
|
|
8
|
+
- `plan-change`: impact and guardrail validation before write.
|
|
9
|
+
- `apply-change`: controlled write after explicit validation.
|
|
10
|
+
- `verify-change`: post-apply verification.
|
|
11
|
+
|
|
12
|
+
## Expected Inputs
|
|
13
|
+
- Environment context (`region`, profile if relevant).
|
|
14
|
+
- Target resource names.
|
|
15
|
+
- Desired workflow/trigger fields.
|
|
16
|
+
- ETL diagnostic context (database/table, partition expectations).
|
|
17
|
+
|
|
18
|
+
## Mandatory Sequence
|
|
19
|
+
1. `read`: fetch current state with `get/list` tools.
|
|
20
|
+
2. `plan`: summarize intended impact and allowed fields.
|
|
21
|
+
3. `validate`: confirm allowlist match, no secrets, and scope fit.
|
|
22
|
+
4. `apply`: run create/update with explicit `dryRun` intent.
|
|
23
|
+
5. `verify`: read again and compare expected vs observed state.
|
|
24
|
+
|
|
25
|
+
## Degradation Rules
|
|
26
|
+
- If permissions fail, switch to read-only diagnostics and emit actionable IAM/config hints.
|
|
27
|
+
- If resource missing in update flow, reject write and propose create flow.
|
|
28
|
+
- If catalog metadata is incomplete, return bounded diagnosis and next checks.
|
|
29
|
+
|
|
30
|
+
## Rejection Rules
|
|
31
|
+
- Reject ambiguous write requests with missing target name or mutable field intent.
|
|
32
|
+
- Reject any request containing plain-text secrets.
|
|
33
|
+
- Reject writes outside allowed name prefixes when enforcement is enabled.
|
|
34
|
+
- Reject out-of-scope requests (jobs/crawlers write in V1).
|
|
35
|
+
|
|
36
|
+
## Safe Change Guidelines
|
|
37
|
+
- Prefer `dryRun: true` on first pass.
|
|
38
|
+
- Keep updates minimal and explicit (no blind patching).
|
|
39
|
+
- Always verify with follow-up `get` call.
|
|
40
|
+
|
|
41
|
+
## Out-of-Scope Guidelines
|
|
42
|
+
- Job/Crawler write changes: reject in V1 and route to roadmap.
|
|
43
|
+
- Destructive flows: reject unless future explicit capability exists.
|
|
44
|
+
|
|
45
|
+
See:
|
|
46
|
+
- `skills/kansodata-glue-operator/docs/examples.md`
|
|
47
|
+
- `skills/kansodata-glue-operator/docs/scope.md`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Safe Diagnostic Request
|
|
4
|
+
Input:
|
|
5
|
+
- "Explain why `push_down_predicate` is not reducing scan for `analytics.fact_orders`."
|
|
6
|
+
|
|
7
|
+
Expected flow:
|
|
8
|
+
1. `glue_get_catalog_table`
|
|
9
|
+
2. `glue_get_catalog_partitions_sample`
|
|
10
|
+
3. `glue_explain_partitioning`
|
|
11
|
+
4. Summarize partition-key alignment and predicate guidance.
|
|
12
|
+
|
|
13
|
+
## Safe Write Request
|
|
14
|
+
Input:
|
|
15
|
+
- "Update trigger `kdo-sales-schedule` cron to 02:00 UTC."
|
|
16
|
+
|
|
17
|
+
Expected flow:
|
|
18
|
+
1. `glue_get_trigger`
|
|
19
|
+
2. impact summary
|
|
20
|
+
3. `glue_update_trigger` with explicit schedule field
|
|
21
|
+
4. `glue_get_trigger` verification
|
|
22
|
+
|
|
23
|
+
## Ambiguous Request
|
|
24
|
+
Input:
|
|
25
|
+
- "Fix my workflow please."
|
|
26
|
+
|
|
27
|
+
Expected response:
|
|
28
|
+
- Reject as ambiguous.
|
|
29
|
+
- Ask for exact workflow name, intended field changes, and expected outcome.
|
|
30
|
+
|
|
31
|
+
## Must Reject
|
|
32
|
+
Input:
|
|
33
|
+
- "Create trigger with token=abc123 in parameters."
|
|
34
|
+
|
|
35
|
+
Expected response:
|
|
36
|
+
- Reject due to secret-like payload.
|
|
37
|
+
|
|
38
|
+
## Out of Scope (V1)
|
|
39
|
+
Input:
|
|
40
|
+
- "Update Glue job script location and worker settings."
|
|
41
|
+
|
|
42
|
+
Expected response:
|
|
43
|
+
- Reject write request as out-of-scope in V1.
|
|
44
|
+
- Suggest read-only diagnostics or roadmap path.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Scope Contract
|
|
2
|
+
|
|
3
|
+
## In Scope (V1)
|
|
4
|
+
- Workflow writes:
|
|
5
|
+
- create
|
|
6
|
+
- update
|
|
7
|
+
- Trigger writes:
|
|
8
|
+
- create
|
|
9
|
+
- update
|
|
10
|
+
- Read/diagnostics:
|
|
11
|
+
- workflows
|
|
12
|
+
- triggers
|
|
13
|
+
- catalog tables
|
|
14
|
+
- partition samples
|
|
15
|
+
- partition explanation guidance
|
|
16
|
+
|
|
17
|
+
## Out of Scope (V1)
|
|
18
|
+
- Any Job write operation.
|
|
19
|
+
- Any Crawler write operation.
|
|
20
|
+
- Destructive default operations.
|
|
21
|
+
- Unvalidated free-form patches against Glue resources.
|
|
22
|
+
|
|
23
|
+
## Safety Contract
|
|
24
|
+
- Enforce read-before-write for updates.
|
|
25
|
+
- Block secret-like payloads.
|
|
26
|
+
- Respect prefix allowlist when enabled.
|
|
27
|
+
- Prefer dry-run defaults and explicit opt-out for apply.
|
|
28
|
+
|
|
29
|
+
## Diagnostic Coverage
|
|
30
|
+
- Supported:
|
|
31
|
+
- partition key visibility
|
|
32
|
+
- sampled partition values
|
|
33
|
+
- guidance for `from_catalog` + `push_down_predicate`
|
|
34
|
+
- Not supported:
|
|
35
|
+
- notebook parsing
|
|
36
|
+
- runtime Spark plan analysis
|
|
37
|
+
- proprietary ETL framework introspection
|