opencode-thrum-pro 0.1.1 → 0.1.3
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/assets/commands/thrum-_stamp-protocol.md +65 -0
- package/assets/skills/brainstorm-steward/SKILL.md +15 -0
- package/assets/skills/choosing-subagent-models/SKILL.md +19 -11
- package/assets/skills/conversation-only-context/SKILL.md +186 -0
- package/assets/skills/coordinator-dispatching-work/SKILL.md +28 -8
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +68 -0
- package/assets/skills/coordinator-merging-code/SKILL.md +24 -0
- package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +11 -7
- package/assets/skills/efficient-multi-agent-research/SKILL.md +7 -6
- package/assets/skills/persistent-watcher-archetype/SKILL.md +80 -15
- package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +123 -0
- package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +379 -0
- package/assets/skills/prime-agent/SKILL.md +2 -4
- package/assets/skills/project-setup/SKILL.md +118 -21
- package/assets/skills/update-queue/SKILL.md +3 -1
- package/assets/thrum_allowlist.json +39 -0
- package/dist/allowlist-sync.test.d.ts +1 -0
- package/dist/allowlist-sync.test.js +44 -0
- package/dist/index.js +24 -1
- package/dist/installer.d.ts +29 -0
- package/dist/installer.js +356 -1
- package/dist/installer.permissions.test.d.ts +1 -0
- package/dist/installer.permissions.test.js +602 -0
- package/dist/permission-fixture.integration.test.d.ts +1 -0
- package/dist/permission-fixture.integration.test.js +506 -0
- package/package.json +3 -2
|
@@ -44,7 +44,45 @@ grep -E 'verify=Ready:Yes([[:space:]]|-->|$)' "$PLAN_FILE" \
|
|
|
44
44
|
|| grep -E 'verify=PREDATES([[:space:]]|-->|$)' "$PLAN_FILE"
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
**Fourth check — the stamp must BIND, not just be PRESENT.** A stamp's
|
|
48
|
+
presence proves a review happened; it does not prove the stamp still
|
|
49
|
+
describes the artifact in front of you. Parse the binding keys from the
|
|
50
|
+
**highest-cycle** (last-appended) `stage=plan` line — stamps are only ever
|
|
51
|
+
appended, never reordered, so `tail -1` is the binding verdict; never `sort`
|
|
52
|
+
(a `cycle=10` line must beat `cycle=9`, which a lexical sort inverts) — then
|
|
53
|
+
re-derive the current values per `_stamp-protocol.md` § "Review-object
|
|
54
|
+
binding" and compare:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# SOURCE_FILE = the LOCKED brainstorm (+ design spec, if any) this plan was reviewed against
|
|
58
|
+
LINE=$(grep '^<!-- THRUM-REVIEW: stage=plan ' "$PLAN_FILE" | tail -1)
|
|
59
|
+
|
|
60
|
+
# An OVERRIDE on this line already satisfies the fourth check (same escape as
|
|
61
|
+
# the first check) — short-circuit BEFORE the missing-keys exit below, or a
|
|
62
|
+
# legitimate OVERRIDE stamp that omits plan_obj/src_lock is wrongly rejected.
|
|
63
|
+
if ! grep -qE 'verdict=OVERRIDE([[:space:]]|-->|$)' <<<"$LINE"; then
|
|
64
|
+
STAMPED_OBJ=$(sed -n 's/.*plan_obj=\([0-9a-f]\{40,64\}\).*/\1/p' <<<"$LINE")
|
|
65
|
+
STAMPED_LOCK=$(sed -n 's/.*src_lock=\([0-9a-f]\{40,64\}\).*/\1/p' <<<"$LINE")
|
|
66
|
+
|
|
67
|
+
# Missing keys fails exactly like a missing verify= — no silent-omission path.
|
|
68
|
+
[ -n "$STAMPED_OBJ" ] && [ -n "$STAMPED_LOCK" ] || {
|
|
69
|
+
echo "review stamp missing plan_obj/src_lock binding keys" >&2; exit 1; }
|
|
70
|
+
|
|
71
|
+
CURRENT_OBJ=$(grep -v '^<!-- THRUM-REVIEW:' "$PLAN_FILE" | git hash-object --no-filters --stdin)
|
|
72
|
+
CURRENT_LOCK=$(git hash-object --no-filters "$SOURCE_FILE")
|
|
73
|
+
|
|
74
|
+
[ "$STAMPED_OBJ" = "$CURRENT_OBJ" ] \
|
|
75
|
+
|| { echo "review stamp does not bind the current plan object" >&2; exit 1; }
|
|
76
|
+
[ "$STAMPED_LOCK" = "$CURRENT_LOCK" ] \
|
|
77
|
+
|| { echo "review stamp bound to a superseded source LOCK" >&2; exit 1; }
|
|
78
|
+
fi
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
An OVERRIDE on the matched `stage=plan` line already satisfies this fourth
|
|
82
|
+
check (same escape as the first check) — the snippet above short-circuits
|
|
83
|
+
before re-deriving or comparing in that case.
|
|
84
|
+
|
|
85
|
+
All four checks must pass.
|
|
48
86
|
|
|
49
87
|
Notes on the check:
|
|
50
88
|
|
|
@@ -75,29 +113,42 @@ Notes on the check:
|
|
|
75
113
|
`OVERRIDE`. This is what makes `verify-against-source` mandatory in fact,
|
|
76
114
|
not just in name: a plan could otherwise carry `verdict=Ready:Yes` from
|
|
77
115
|
some OTHER reviewer while `verify-against-source` itself never ran.
|
|
116
|
+
- **The binding check fails closed on either mismatch, with no
|
|
117
|
+
silent-omission path** — a stamp missing `plan_obj`/`src_lock` entirely
|
|
118
|
+
fails exactly like a missing `verify=` field (fourth check above). The
|
|
119
|
+
remedy is the same shape as the `verify=` remedy: re-run the plan review so
|
|
120
|
+
the stamp is emitted with live binding keys (`_stamp-protocol.md` § "Review-
|
|
121
|
+
object binding"), or a coordinator adds an explicit `verdict=OVERRIDE`
|
|
122
|
+
(with `reason=`) to the `stage=plan` line — the SAME auditable escape used
|
|
123
|
+
for the first check, not a new mechanism. There is no `PREDATES` value for
|
|
124
|
+
the binding keys themselves; a legacy plan without them either gets
|
|
125
|
+
re-reviewed (which produces the keys) or overridden.
|
|
78
126
|
|
|
79
127
|
If any check fails, **STOP — do not proceed.** Tell the user:
|
|
80
128
|
|
|
81
129
|
> project-setup requires the plan/spec to have passed the planning-loop review
|
|
82
130
|
> (or carry a coordinator override), to carry a `## Deviations from Source`
|
|
83
|
-
> block,
|
|
84
|
-
>
|
|
85
|
-
>
|
|
86
|
-
>
|
|
87
|
-
>
|
|
88
|
-
>
|
|
89
|
-
>
|
|
90
|
-
> `verify
|
|
91
|
-
>
|
|
131
|
+
> block, to carry `verify=Ready:Yes`, `verify=OVERRIDE`, or `verify=PREDATES`
|
|
132
|
+
> evidence that `verify-against-source` specifically ran (or was deliberately
|
|
133
|
+
> waived, or the plan predates the convention), AND for the review stamp to
|
|
134
|
+
> BIND the current plan object and current locked source (`plan_obj`/
|
|
135
|
+
> `src_lock`). The plan at `<PLAN_FILE>` is missing one or more of: the review
|
|
136
|
+
> stamp, the Deviations block, the `verify=` field, or a valid binding — check
|
|
137
|
+
> which with the commands above. Run the plan review first (making sure
|
|
138
|
+
> `verify-against-source` runs, `verify=` is stamped, and `plan_obj`/
|
|
139
|
+
> `src_lock` are computed fresh), obtain a coordinator override, or stamp
|
|
140
|
+
> `verify=PREDATES` if the plan predates the `verify=` convention, then
|
|
141
|
+
> re-invoke project-setup.
|
|
92
142
|
|
|
93
143
|
**Fail closed, not open.** Plans that predate this feature, or that arrive from
|
|
94
|
-
a different flow, will not carry the stamp, the Deviations block,
|
|
95
|
-
`verify=` field — they still bail on all
|
|
96
|
-
`OVERRIDE` stamp for the review-stamp check
|
|
144
|
+
a different flow, will not carry the stamp, the Deviations block, the
|
|
145
|
+
`verify=` field, or the binding keys — they still bail on all four checks. The
|
|
146
|
+
caller must add an `OVERRIDE` stamp for the review-stamp check (which also
|
|
147
|
+
covers the binding check, per the note above) and a `verify=PREDATES` (the
|
|
97
148
|
legacy case — not `verify=OVERRIDE`, which is reserved for an active per-cycle
|
|
98
149
|
waiver) for the verify check, and must author the Deviations block (there is
|
|
99
150
|
no override for its absence), to proceed. Do not silently fall through when
|
|
100
|
-
any of the
|
|
151
|
+
any of the four is absent.
|
|
101
152
|
|
|
102
153
|
## When to Use
|
|
103
154
|
|
|
@@ -901,11 +952,13 @@ prompt file:
|
|
|
901
952
|
<!-- THRUM-GATE: stage=prompt next=dispatch -->
|
|
902
953
|
```
|
|
903
954
|
|
|
904
|
-
2. **After the post-setup prompt review terminates `Ready:Yes`**,
|
|
905
|
-
|
|
955
|
+
2. **After the post-setup prompt review terminates `Ready:Yes`**, compute
|
|
956
|
+
`prompt_obj`/`plan_lock` per `_stamp-protocol.md` § "Review-object binding"
|
|
957
|
+
(strip-then-hash the prompt against itself for `prompt_obj`; plain-hash the
|
|
958
|
+
LOCKED plan for `plan_lock`), then append the verdict stamp:
|
|
906
959
|
|
|
907
960
|
```text
|
|
908
|
-
<!-- THRUM-REVIEW: stage=prompt verdict=Ready:Yes cycle=<N> date=<YYYY-MM-DD> -->
|
|
961
|
+
<!-- THRUM-REVIEW: stage=prompt verdict=Ready:Yes cycle=<N> date=<YYYY-MM-DD> prompt_obj=<blob> plan_lock=<blob> -->
|
|
909
962
|
```
|
|
910
963
|
|
|
911
964
|
This review happens **within the same project-setup session**: after Step 4
|
|
@@ -916,10 +969,54 @@ prompt file:
|
|
|
916
969
|
|
|
917
970
|
Use the exact canonical, case-sensitive form (`Ready:Yes` / `OVERRIDE`; keep
|
|
918
971
|
keys in the fixed order `stage=`, `verdict=`, `cycle=`, `date=` so a literal
|
|
919
|
-
`grep -F` matches).
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
972
|
+
`grep -F` matches).
|
|
973
|
+
|
|
974
|
+
**This stamp is a hard completion requirement, not an optional shortcut.**
|
|
975
|
+
project-setup CANNOT report completion or dispatch-readiness for this session
|
|
976
|
+
until the generated prompt carries a `stage=prompt verdict=Ready:Yes` (or
|
|
977
|
+
`OVERRIDE`) THRUM-REVIEW line with valid `prompt_obj`/`plan_lock` bindings.
|
|
978
|
+
Run the same binding check used at Phase 0 (§ "Fourth check" above), against
|
|
979
|
+
the prompt instead of the plan:
|
|
980
|
+
|
|
981
|
+
```bash
|
|
982
|
+
# PROMPT_FILE = the generated prompt; PLAN_FILE = the LOCKED plan it was reviewed against
|
|
983
|
+
LINE=$(grep '^<!-- THRUM-REVIEW: stage=prompt ' "$PROMPT_FILE" | tail -1)
|
|
984
|
+
[ -n "$LINE" ] || {
|
|
985
|
+
echo "prompt carries no stage=prompt review stamp — cannot report dispatch-ready" >&2
|
|
986
|
+
exit 1
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
# An OVERRIDE on this line already satisfies the check (same escape as
|
|
990
|
+
# Phase 0's fourth check) — short-circuit BEFORE the missing-keys exit below,
|
|
991
|
+
# or a legitimate OVERRIDE stamp that omits prompt_obj/plan_lock is wrongly
|
|
992
|
+
# rejected.
|
|
993
|
+
if ! grep -qE 'verdict=OVERRIDE([[:space:]]|-->|$)' <<<"$LINE"; then
|
|
994
|
+
STAMPED_OBJ=$(sed -n 's/.*prompt_obj=\([0-9a-f]\{40,64\}\).*/\1/p' <<<"$LINE")
|
|
995
|
+
STAMPED_LOCK=$(sed -n 's/.*plan_lock=\([0-9a-f]\{40,64\}\).*/\1/p' <<<"$LINE")
|
|
996
|
+
[ -n "$STAMPED_OBJ" ] && [ -n "$STAMPED_LOCK" ] || {
|
|
997
|
+
echo "review stamp missing prompt_obj/plan_lock binding keys" >&2; exit 1; }
|
|
998
|
+
|
|
999
|
+
CURRENT_OBJ=$(grep -v '^<!-- THRUM-REVIEW:' "$PROMPT_FILE" | git hash-object --no-filters --stdin)
|
|
1000
|
+
CURRENT_LOCK=$(git hash-object --no-filters "$PLAN_FILE")
|
|
1001
|
+
|
|
1002
|
+
[ "$STAMPED_OBJ" = "$CURRENT_OBJ" ] \
|
|
1003
|
+
|| { echo "review stamp does not bind the current prompt object" >&2; exit 1; }
|
|
1004
|
+
[ "$STAMPED_LOCK" = "$CURRENT_LOCK" ] \
|
|
1005
|
+
|| { echo "review stamp bound to a superseded plan LOCK" >&2; exit 1; }
|
|
1006
|
+
fi
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
An OVERRIDE on the matched line already satisfies this check (same escape as
|
|
1010
|
+
Phase 0's fourth check) — the snippet above short-circuits before re-deriving
|
|
1011
|
+
or comparing in that case.
|
|
1012
|
+
|
|
1013
|
+
At dispatch, the coordinator greps the prompt for this stamp. On a
|
|
1014
|
+
project-setup-produced prompt it is ALWAYS present — project-setup will not
|
|
1015
|
+
have reported completion without it — so its absence on such a prompt is an
|
|
1016
|
+
ANOMALY requiring the full pre-dispatch review, never a sanctioned shortcut
|
|
1017
|
+
for skipping it. (Pre-feature prompts and prompts from non-project-setup
|
|
1018
|
+
flows are a separate, narrower carve-out — see
|
|
1019
|
+
`coordinator-dispatching-work`.)
|
|
923
1020
|
|
|
924
1021
|
## Common Mistakes
|
|
925
1022
|
|
|
@@ -112,7 +112,9 @@ Give each sub-agent:
|
|
|
112
112
|
`merge-base`, `status` ONLY — never `checkout`/`reset`/`restore`/`stash`/
|
|
113
113
|
`clean`/`rebase`/`commit`/`push`, in any directory; never enter another
|
|
114
114
|
worktree.
|
|
115
|
-
- pinned `model:`
|
|
115
|
+
- pinned `model:` (sonnet; intended tier is low for mechanical lookups — the
|
|
116
|
+
Agent tool takes no `effort`, so carry the tier via the agent definition or
|
|
117
|
+
the tmux launch flags).
|
|
116
118
|
|
|
117
119
|
## Step 5 — Add missing committed work
|
|
118
120
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"_supersedes": "the earlier watcher-settings allowlist spec (single-watcher restart-flow scope)",
|
|
4
|
+
"command_patterns": [
|
|
5
|
+
"thrum"
|
|
6
|
+
],
|
|
7
|
+
"read_paths": [
|
|
8
|
+
".claude/skills",
|
|
9
|
+
".claude/commands",
|
|
10
|
+
".codex/skills",
|
|
11
|
+
".opencode/skills",
|
|
12
|
+
".thrum"
|
|
13
|
+
],
|
|
14
|
+
"global_read_paths": {
|
|
15
|
+
"claude": [
|
|
16
|
+
"~/.claude/plugins/cache/thrum",
|
|
17
|
+
"~/.local/bin"
|
|
18
|
+
],
|
|
19
|
+
"codex": [
|
|
20
|
+
"~/.codex/skills",
|
|
21
|
+
"~/.codex/plugins/cache/thrum-marketplace/thrum",
|
|
22
|
+
"~/.local/bin"
|
|
23
|
+
],
|
|
24
|
+
"opencode": [
|
|
25
|
+
"~/.local/bin"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"owner_authorized_exceptions": {
|
|
29
|
+
"claude": [
|
|
30
|
+
"/private/tmp"
|
|
31
|
+
],
|
|
32
|
+
"codex": [
|
|
33
|
+
"/private/tmp"
|
|
34
|
+
],
|
|
35
|
+
"opencode": [
|
|
36
|
+
"/private/tmp"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Drift guard (allowlist round 2, finding 9): the canonical allowlist
|
|
2
|
+
// (internal/permissions/thrum_allowlist.json, Go-owned) is copied verbatim
|
|
3
|
+
// into this plugin's bundled asset (opencode-plugin/assets/thrum_allowlist.
|
|
4
|
+
// json) by scripts/sync-skills.sh's sync_opencode step, since TypeScript
|
|
5
|
+
// cannot import a Go package. This test fails LOUDLY the moment the two
|
|
6
|
+
// diverge — a hand-edit of either copy, or a Go-side change that never got
|
|
7
|
+
// synced.
|
|
8
|
+
//
|
|
9
|
+
// Deliberately compares RAW BYTES, not parsed-then-reserialized JSON: a
|
|
10
|
+
// round-trip through JSON.parse/JSON.stringify would normalize whitespace,
|
|
11
|
+
// key order, and formatting, and could mask a real drift (e.g. a
|
|
12
|
+
// re-ordered or re-indented — but content-different — copy would compare
|
|
13
|
+
// "equal" after reserialization while still being a byte-for-byte
|
|
14
|
+
// divergence from the Go source of truth).
|
|
15
|
+
import { test } from "node:test";
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import fs from "fs";
|
|
18
|
+
import path from "path";
|
|
19
|
+
// This test file compiles to dist/allowlist-sync.test.js (flat src ->
|
|
20
|
+
// flat dist, see tsconfig rootDir/outDir), so at runtime
|
|
21
|
+
// path.dirname(import.meta.url) is opencode-plugin/dist. One level up is
|
|
22
|
+
// opencode-plugin/ (matches the existing ALLOWLIST_ASSET_PATH convention in
|
|
23
|
+
// installer.permissions.test.ts); two levels up is the repo root, from
|
|
24
|
+
// which internal/permissions/ is reachable.
|
|
25
|
+
const HERE = path.dirname(new URL(import.meta.url).pathname);
|
|
26
|
+
const PLUGIN_ROOT = path.resolve(HERE, "..");
|
|
27
|
+
const REPO_ROOT = path.resolve(PLUGIN_ROOT, "..");
|
|
28
|
+
const OPENCODE_COPY = path.join(PLUGIN_ROOT, "assets", "thrum_allowlist.json");
|
|
29
|
+
const CANONICAL_SOURCE = path.join(REPO_ROOT, "internal", "permissions", "thrum_allowlist.json");
|
|
30
|
+
test("opencode-plugin/assets/thrum_allowlist.json is byte-identical to internal/permissions/thrum_allowlist.json", (t) => {
|
|
31
|
+
// The canonical source only exists in the monorepo (github.com/leonletto/thrum);
|
|
32
|
+
// the public standalone opencode-thrum-pro repo this test also ships in does not
|
|
33
|
+
// carry internal/permissions/, so skip gracefully there instead of failing —
|
|
34
|
+
// mirrors the binary-absent skip idiom in permission-fixture.integration.test.ts.
|
|
35
|
+
if (!fs.existsSync(CANONICAL_SOURCE)) {
|
|
36
|
+
t.skip(`canonical source not found at ${CANONICAL_SOURCE} — expected outside the monorepo (e.g. public opencode-thrum-pro), skipping drift check`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
assert.ok(fs.existsSync(OPENCODE_COPY), `synced copy not found at ${OPENCODE_COPY}`);
|
|
40
|
+
const canonical = fs.readFileSync(CANONICAL_SOURCE);
|
|
41
|
+
const copy = fs.readFileSync(OPENCODE_COPY);
|
|
42
|
+
assert.ok(canonical.equals(copy), "opencode-plugin/assets/thrum_allowlist.json has drifted from internal/permissions/thrum_allowlist.json — " +
|
|
43
|
+
"re-run scripts/sync-skills.sh (sync_opencode step) to resync, never hand-edit either copy independently");
|
|
44
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { installAssets } from "./installer.js";
|
|
1
|
+
import { installAssets, installPermissions } from "./installer.js";
|
|
2
2
|
import { shellEnvHook } from "./hooks/shell-env.js";
|
|
3
3
|
import { blockSyncCdHook } from "./hooks/block-sync-cd.js";
|
|
4
4
|
const TOOL_MAPPING = `
|
|
@@ -13,6 +13,29 @@ When Thrum skills reference Claude Code tool names, use these OpenCode equivalen
|
|
|
13
13
|
`.trim();
|
|
14
14
|
const server = async (ctx) => {
|
|
15
15
|
await installAssets(ctx);
|
|
16
|
+
// Runs unconditionally (not version-gated like installAssets above): it's
|
|
17
|
+
// cheap and idempotent, and gating it on the skills-version marker would
|
|
18
|
+
// skip re-merging the allowlist for users who already had the plugin
|
|
19
|
+
// installed before this permission block existed (allowlist).
|
|
20
|
+
//
|
|
21
|
+
// installPermissions() throws when the user's existing global
|
|
22
|
+
// opencode.json is present but malformed (unreadable or invalid JSON) —
|
|
23
|
+
// deliberately, so we never silently overwrite it (allowlist landing-
|
|
24
|
+
// blocker). Catch and log here rather than letting it become an unhandled
|
|
25
|
+
// rejection that would abort plugin bootstrap entirely; every other hook
|
|
26
|
+
// this plugin provides should still register.
|
|
27
|
+
try {
|
|
28
|
+
await installPermissions();
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
await ctx.client.app.log({
|
|
32
|
+
body: {
|
|
33
|
+
service: "opencode-thrum",
|
|
34
|
+
level: "error",
|
|
35
|
+
message: `failed to install thrum permission allowlist (leaving your opencode.json untouched): ${err.message}`,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
16
39
|
return {
|
|
17
40
|
"shell.env": shellEnvHook(ctx),
|
|
18
41
|
"tool.execute.before": blockSyncCdHook(),
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,2 +1,31 @@
|
|
|
1
1
|
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
export declare function getConfigDir(): string;
|
|
2
3
|
export declare function installAssets(ctx: PluginInput): Promise<void>;
|
|
4
|
+
interface AllowlistSource {
|
|
5
|
+
version: number;
|
|
6
|
+
command_patterns: string[];
|
|
7
|
+
read_paths: string[];
|
|
8
|
+
owner_authorized_exceptions?: Record<string, string[]>;
|
|
9
|
+
global_read_paths?: Record<string, string[]>;
|
|
10
|
+
}
|
|
11
|
+
type PermissionAction = "ask" | "allow" | "deny";
|
|
12
|
+
type PermissionRuleMap = Record<string, PermissionAction>;
|
|
13
|
+
interface OpenCodeConfig {
|
|
14
|
+
permission?: {
|
|
15
|
+
bash?: PermissionRuleMap | PermissionAction;
|
|
16
|
+
read?: PermissionRuleMap | PermissionAction;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
};
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export declare function bashExactPatternFor(commandPattern: string): string;
|
|
22
|
+
export declare function bashPatternFor(commandPattern: string): string;
|
|
23
|
+
export declare function readPatternFor(readPath: string): string;
|
|
24
|
+
export declare function resolveHomePath(p: string, homeDir?: string): string;
|
|
25
|
+
export declare function readFilePatternFor(filePath: string): string;
|
|
26
|
+
export declare function loadAllowlist(assetPath?: string): AllowlistSource;
|
|
27
|
+
export declare function mergePermissions(config: OpenCodeConfig, allowlist: AllowlistSource, extraReadPatterns?: string[], homeDir?: string): OpenCodeConfig;
|
|
28
|
+
export declare function writeConfig(configPath: string, config: OpenCodeConfig): void;
|
|
29
|
+
export declare function opencodeGlobalReadPaths(configDir: string): string[];
|
|
30
|
+
export declare function installPermissions(configDir?: string, homeDir?: string): Promise<void>;
|
|
31
|
+
export {};
|