@samirosamsam/aim 0.1.0 → 0.1.1
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/.codex-plugin/plugin.json +1 -1
- package/README.md +13 -0
- package/package.json +1 -1
- package/skills/aim/SKILL.md +25 -3
- package/src/engine.js +15 -2
package/README.md
CHANGED
|
@@ -46,6 +46,19 @@ npx -y @samirosamsam/aim@latest rule add 'empêche de modifier package.json'
|
|
|
46
46
|
npx -y @samirosamsam/aim@latest rule add 'empêche les calls GitHub qui ajoutent des collaborators'
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
For SaaS data targets described by a title or label, use Codex/provider tools first to resolve the concrete resource, then write the rule with `capture`:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx -y @samirosamsam/aim@latest capture \
|
|
53
|
+
--provider notion \
|
|
54
|
+
--tool fetch \
|
|
55
|
+
--args '{"url":"https://www.notion.so/..."}' \
|
|
56
|
+
--effect deny \
|
|
57
|
+
--agent codex \
|
|
58
|
+
--connection notion:codex \
|
|
59
|
+
--policy ~/.codex/aim/policy.json
|
|
60
|
+
```
|
|
61
|
+
|
|
49
62
|
Codex then calls the AIM hook before supported tool calls. A blocked Bash call returns the Codex `PreToolUse` deny shape:
|
|
50
63
|
|
|
51
64
|
```json
|
package/package.json
CHANGED
package/skills/aim/SKILL.md
CHANGED
|
@@ -17,7 +17,14 @@ npx -y @samirosamsam/aim@latest setup --json
|
|
|
17
17
|
|
|
18
18
|
If Codex reports that hooks need review, tell the user to run `/hooks`, inspect the AIM hook, and trust it. Do not claim active enforcement until the hook is trusted and a proof call blocks.
|
|
19
19
|
|
|
20
|
-
2.
|
|
20
|
+
2. Choose the smallest enforceable path:
|
|
21
|
+
|
|
22
|
+
- For Bash commands and file edits, use `rule add`.
|
|
23
|
+
- For external data or SaaS access, first discover the concrete resource with that provider's tools, then use `capture`.
|
|
24
|
+
- If the user gives a human label such as a page title, folder name, channel name, repo label, database name, or "all subpages", do not reject it as "not a resource". Search/list/fetch with the provider plugin or MCP tools, pick the best exact match when confidence is high, and explain the choice. Ask only when several plausible matches remain or when a broad wildcard would be required.
|
|
25
|
+
- For hierarchical requests such as subpages, folders, databases, repos, or projects, enumerate the concrete children when the provider tools expose them and add rules for each resolved resource. If the provider cannot enumerate future children, block the resolved current resources and state that new children need another rule.
|
|
26
|
+
|
|
27
|
+
For local Codex rules:
|
|
21
28
|
|
|
22
29
|
```bash
|
|
23
30
|
npx -y @samirosamsam/aim@latest rule add "<what the user wants to prevent>" --json
|
|
@@ -31,6 +38,21 @@ npx -y @samirosamsam/aim@latest rule add "empêche de modifier package.json" --j
|
|
|
31
38
|
npx -y @samirosamsam/aim@latest rule add "empêche les calls GitHub qui ajoutent des collaborators" --json
|
|
32
39
|
```
|
|
33
40
|
|
|
41
|
+
For resolved MCP resources:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx -y @samirosamsam/aim@latest capture \
|
|
45
|
+
--provider "<provider>" \
|
|
46
|
+
--tool "<representative MCP tool>" \
|
|
47
|
+
--args '<representative MCP args JSON>' \
|
|
48
|
+
--resource "<stable provider resource id or path>" \
|
|
49
|
+
--effect deny \
|
|
50
|
+
--agent codex \
|
|
51
|
+
--connection "<provider>:codex" \
|
|
52
|
+
--policy ~/.codex/aim/policy.json \
|
|
53
|
+
--json
|
|
54
|
+
```
|
|
55
|
+
|
|
34
56
|
3. Prove the guardrail with a representative hook input before reporting success. Pick the proof that matches the rule:
|
|
35
57
|
|
|
36
58
|
```bash
|
|
@@ -58,7 +80,7 @@ npx -y @samirosamsam/aim@latest rule list --json
|
|
|
58
80
|
|
|
59
81
|
## Advanced Commands
|
|
60
82
|
|
|
61
|
-
Use `
|
|
83
|
+
Use `compile`, `add`, or `check` only for lower-level policy debugging. The normal public workflow is `setup`, then `rule add` for local Codex resources or provider discovery plus `capture` for MCP resources, then proof, then report.
|
|
62
84
|
|
|
63
85
|
```bash
|
|
64
86
|
npx -y @samirosamsam/aim@latest capture \
|
|
@@ -75,7 +97,7 @@ If a command returns `questions`, ask for the missing command, file path, provid
|
|
|
75
97
|
|
|
76
98
|
## Scope
|
|
77
99
|
|
|
78
|
-
- For Codex enforcement, prefer `rule add` over `compile`/`add`;
|
|
100
|
+
- For Codex enforcement, prefer `rule add` for Bash/files and `capture` for resolved MCP resources over `compile`/`add`; both write rules intended for the `PreToolUse` hook.
|
|
79
101
|
- Prefer narrow resource patterns over `*`.
|
|
80
102
|
- Codex hook guardrails are default-allow: no matching block means the tool call proceeds.
|
|
81
103
|
- Treat `deny` as higher priority than `approval`, and `approval` as higher priority than `allow`.
|
package/src/engine.js
CHANGED
|
@@ -214,7 +214,12 @@ export function compileCodexRulePrompt(prompt, context = {}) {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
if (drafts.length === 0) {
|
|
217
|
-
|
|
217
|
+
const providers = detectProviders(normalized).filter((provider) => provider !== "*");
|
|
218
|
+
if (providers.length > 0) {
|
|
219
|
+
questions.push(`Resolve the ${providers.join("/")} resource with that provider's search/list/fetch tools, then add an AIM capture rule with the stable resource id or path.`);
|
|
220
|
+
} else {
|
|
221
|
+
questions.push("Specify a Bash command, file path, or MCP provider/tool/resource to block.");
|
|
222
|
+
}
|
|
218
223
|
}
|
|
219
224
|
|
|
220
225
|
return { drafts: uniqueDrafts(drafts), questions };
|
|
@@ -531,7 +536,7 @@ function inferGithubCall(tool, args) {
|
|
|
531
536
|
}
|
|
532
537
|
|
|
533
538
|
function inferNotionCall(tool, args) {
|
|
534
|
-
const page = cleanPart(args.page_id ?? args.pageId ?? args.id);
|
|
539
|
+
const page = cleanPart(args.page_id ?? args.pageId ?? args.id ?? notionPageId(args.url ?? args.page_url ?? args.pageUrl));
|
|
535
540
|
const database = cleanPart(args.database_id ?? args.databaseId);
|
|
536
541
|
if (page) return { access: inferAccess(tool), resource: `notion/pages/${page}` };
|
|
537
542
|
if (database) return { access: inferAccess(tool), resource: `notion/databases/${database}` };
|
|
@@ -570,6 +575,14 @@ function githubRepo(args, suffix = "") {
|
|
|
570
575
|
return owner && repo ? `repo/${owner}/${repo}${suffix}` : "*";
|
|
571
576
|
}
|
|
572
577
|
|
|
578
|
+
function notionPageId(value) {
|
|
579
|
+
const text = String(value ?? "");
|
|
580
|
+
const dashed = text.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
|
|
581
|
+
if (dashed) return dashed[0];
|
|
582
|
+
const compact = text.match(/[0-9a-f]{32}/i);
|
|
583
|
+
return compact?.[0] ?? "";
|
|
584
|
+
}
|
|
585
|
+
|
|
573
586
|
function reasonFor(effect, access, resourcePattern) {
|
|
574
587
|
if (effect === "deny") return `Block ${access} on ${resourcePattern}.`;
|
|
575
588
|
if (effect === "approval") return `Require human approval for ${access} on ${resourcePattern}.`;
|