jorgex-stack 1.0.22 → 1.0.24
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/README.md +2 -0
- package/dist/cli.js +81 -20
- package/package.json +1 -1
- package/stack/config/defaults.json +44 -10
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@ For development from a clone, run the same commands through `pnpm cli <command>`
|
|
|
24
24
|
|
|
25
25
|
Every command supports `--dry-run`, `--yes`, and `--target-dir <dir>` for testing without touching the real config. Writes create automatic backups and verify idempotency; merges into user config are surgical (marked markdown sections, JSON/TOML upserts), so user-owned content is never touched.
|
|
26
26
|
|
|
27
|
+
Runtime defaults are documented in [docs/references/permissions.md](docs/references/permissions.md) for permissions and [docs/references/models.md](docs/references/models.md) for model selection, GPT-5.6 subagent tiers, and orchestrator inheritance.
|
|
28
|
+
|
|
27
29
|
### Modes: Human and Programmatic
|
|
28
30
|
|
|
29
31
|
`install` and `sync` accept two mutually-exclusive installation modes. The choice is global (not per runtime) and is saved in `~/.jorgex-stack/install-mode.json` on first run; subsequent `sync` calls reuse it. Re-run `install` with `--mode` to switch.
|
package/dist/cli.js
CHANGED
|
@@ -179,21 +179,22 @@ function resolveAgentModel(models, agentName, tier) {
|
|
|
179
179
|
}
|
|
180
180
|
var DEFAULT_MODEL_MAP = {
|
|
181
181
|
opencode: {
|
|
182
|
-
strong: { model: "openai/gpt-5.
|
|
183
|
-
standard: { model: "openai/gpt-5.
|
|
184
|
-
cheap: { model: "
|
|
182
|
+
strong: { model: "openai/gpt-5.6-terra", variant: "xhigh" },
|
|
183
|
+
standard: { model: "openai/gpt-5.6-terra", variant: "xhigh" },
|
|
184
|
+
cheap: { model: "openai/gpt-5.6-luna", variant: "medium" }
|
|
185
185
|
},
|
|
186
186
|
"claude-code": {
|
|
187
187
|
strong: { model: "fable" },
|
|
188
188
|
standard: { model: "sonnet" },
|
|
189
189
|
cheap: { model: "haiku" }
|
|
190
190
|
},
|
|
191
|
-
//
|
|
192
|
-
//
|
|
191
|
+
// El primary (orchestrator) no usa estos tiers: tanto el profile de CLI como
|
|
192
|
+
// la skill de la app heredan el modelo elegido por el usuario. Estos defaults
|
|
193
|
+
// son solo para subagentes; variant → model_reasoning_effort.
|
|
193
194
|
codex: {
|
|
194
|
-
strong: { model: "
|
|
195
|
-
standard: { model: "
|
|
196
|
-
cheap: { model: "
|
|
195
|
+
strong: { model: "gpt-5.6-terra", variant: "xhigh" },
|
|
196
|
+
standard: { model: "gpt-5.6-terra", variant: "xhigh" },
|
|
197
|
+
cheap: { model: "gpt-5.6-luna", variant: "medium" }
|
|
197
198
|
}
|
|
198
199
|
};
|
|
199
200
|
function modelMapFile() {
|
|
@@ -614,11 +615,17 @@ ${agent.body}`,
|
|
|
614
615
|
planMainConfig(canonical, ctx) {
|
|
615
616
|
const file = path7.join(ctx.configDir, "opencode.json");
|
|
616
617
|
const { pluginsDir } = this.paths(ctx.configDir);
|
|
617
|
-
const
|
|
618
|
+
const original = readTextIfExists(file);
|
|
619
|
+
const contentSource = original === null || original.trim() === "" ? null : original;
|
|
620
|
+
const isFreshConfig = contentSource === null;
|
|
621
|
+
const content = upsertJson(contentSource, (root) => {
|
|
618
622
|
root["$schema"] ??= "https://opencode.ai/config.json";
|
|
619
623
|
const defaults = loadCanonicalDefaults(ctx.stackDir)["opencode"];
|
|
620
|
-
if (defaults?.["permission"] !== void 0
|
|
624
|
+
if (isFreshConfig && defaults?.["permission"] !== void 0) {
|
|
621
625
|
root["permission"] = defaults["permission"];
|
|
626
|
+
ctx.warnings.push(
|
|
627
|
+
"OpenCode: fresh config enables read-anywhere via external_directory:*; edits, web egress and arbitrary bash remain approval-gated, but broad local reads can expose secrets not covered by deny rules."
|
|
628
|
+
);
|
|
622
629
|
}
|
|
623
630
|
const mcp = root["mcp"] ??= {};
|
|
624
631
|
for (const [name, server] of Object.entries(canonical.servers)) {
|
|
@@ -818,12 +825,19 @@ ${agent.body}`,
|
|
|
818
825
|
planHooks(canonical, ctx) {
|
|
819
826
|
const actions = [];
|
|
820
827
|
const { scriptsDir } = this.paths(ctx.configDir);
|
|
828
|
+
const original = readTextIfExists(path8.join(ctx.configDir, "settings.json"));
|
|
829
|
+
const contentSource = original === null || original.trim() === "" ? null : original;
|
|
821
830
|
const settingsFile = path8.join(ctx.configDir, "settings.json");
|
|
822
|
-
let content = upsertNativeHooks(
|
|
831
|
+
let content = upsertNativeHooks(contentSource, canonical, scriptsDir);
|
|
823
832
|
const defaults = loadCanonicalDefaults(ctx.stackDir)["claude-code"];
|
|
824
|
-
if (defaults?.["permissions"] !== void 0) {
|
|
833
|
+
if (contentSource === null && defaults?.["permissions"] !== void 0) {
|
|
825
834
|
content = upsertJson(content, (root) => {
|
|
826
|
-
if (
|
|
835
|
+
if (root["permissions"] === void 0) {
|
|
836
|
+
root["permissions"] = defaults["permissions"];
|
|
837
|
+
ctx.warnings.push(
|
|
838
|
+
"Claude Code: fresh config enables read-anywhere via Read/Grep/Glob allow rules; shell, writes and web egress remain approval-gated, but broad local reads can expose secrets not covered by deny rules."
|
|
839
|
+
);
|
|
840
|
+
}
|
|
827
841
|
});
|
|
828
842
|
}
|
|
829
843
|
actions.push({ kind: "write", target: settingsFile, content });
|
|
@@ -1026,13 +1040,52 @@ ${body}`
|
|
|
1026
1040
|
},
|
|
1027
1041
|
planMainConfig(canonical, ctx) {
|
|
1028
1042
|
const file = path9.join(ctx.configDir, "config.toml");
|
|
1029
|
-
|
|
1030
|
-
const
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
const
|
|
1043
|
+
const original = readTextIfExists(file);
|
|
1044
|
+
const contentSource = original === null || original.trim() === "" ? null : original;
|
|
1045
|
+
let content = contentSource;
|
|
1046
|
+
if (contentSource === null) {
|
|
1047
|
+
const defaults = loadCanonicalDefaults(ctx.stackDir)["codex"] ?? {};
|
|
1048
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
1049
|
+
const line = `${key} = ${tomlString(String(value))}
|
|
1034
1050
|
`;
|
|
1035
|
-
|
|
1051
|
+
content = content === null ? line : line + content;
|
|
1052
|
+
}
|
|
1053
|
+
ctx.warnings.push(
|
|
1054
|
+
"Codex: fresh config enables read-anywhere via the jorgex-read-anywhere permission profile; broad local reads can expose secrets not covered by deny rules."
|
|
1055
|
+
);
|
|
1056
|
+
content = upsertTomlSection(content, "permissions.jorgex-read-anywhere", 'extends = ":workspace"');
|
|
1057
|
+
content = upsertTomlSection(
|
|
1058
|
+
content,
|
|
1059
|
+
"permissions.jorgex-read-anywhere.filesystem",
|
|
1060
|
+
[
|
|
1061
|
+
'":root" = "read"',
|
|
1062
|
+
'"*.env" = "deny"',
|
|
1063
|
+
'"*.env.*" = "deny"',
|
|
1064
|
+
'"~/.ssh/**" = "deny"',
|
|
1065
|
+
'"~/.aws/credentials" = "deny"',
|
|
1066
|
+
'"~/.npmrc" = "deny"',
|
|
1067
|
+
'"~/.git-credentials" = "deny"',
|
|
1068
|
+
'"**/id_rsa" = "deny"',
|
|
1069
|
+
'"**/id_ed25519" = "deny"',
|
|
1070
|
+
'"**/*.pem" = "deny"',
|
|
1071
|
+
'"**/*.key" = "deny"'
|
|
1072
|
+
].join("\n")
|
|
1073
|
+
);
|
|
1074
|
+
content += [
|
|
1075
|
+
'\n[permissions.jorgex-read-anywhere.filesystem.":workspace_roots"]',
|
|
1076
|
+
'"." = "write"',
|
|
1077
|
+
'"*.env" = "deny"',
|
|
1078
|
+
'"*.env.*" = "deny"',
|
|
1079
|
+
'".ssh/**" = "deny"',
|
|
1080
|
+
'".aws/credentials" = "deny"',
|
|
1081
|
+
'".npmrc" = "deny"',
|
|
1082
|
+
'".git-credentials" = "deny"',
|
|
1083
|
+
'"**/id_rsa" = "deny"',
|
|
1084
|
+
'"**/id_ed25519" = "deny"',
|
|
1085
|
+
'"**/*.pem" = "deny"',
|
|
1086
|
+
'"**/*.key" = "deny"',
|
|
1087
|
+
""
|
|
1088
|
+
].join("\n");
|
|
1036
1089
|
}
|
|
1037
1090
|
for (const [name, server] of Object.entries(canonical.servers)) {
|
|
1038
1091
|
const section = `mcp_servers.${name}`;
|
|
@@ -2790,7 +2843,15 @@ import * as p5 from "@clack/prompts";
|
|
|
2790
2843
|
var TIERS = ["strong", "standard", "cheap"];
|
|
2791
2844
|
var EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
2792
2845
|
var CLAUDE_ALIASES = ["fable", "opus", "sonnet", "haiku", "inherit"];
|
|
2793
|
-
var CODEX_MODELS = [
|
|
2846
|
+
var CODEX_MODELS = [
|
|
2847
|
+
"default",
|
|
2848
|
+
"gpt-5.6-sol",
|
|
2849
|
+
"gpt-5.6-terra",
|
|
2850
|
+
"gpt-5.6-luna",
|
|
2851
|
+
"gpt-5.5",
|
|
2852
|
+
"gpt-5.4",
|
|
2853
|
+
"gpt-5.4-mini"
|
|
2854
|
+
];
|
|
2794
2855
|
var CODEX_CUSTOM = "__custom__";
|
|
2795
2856
|
var CANCEL = /* @__PURE__ */ Symbol("cancel");
|
|
2796
2857
|
function opencodeLiveModels(binPath) {
|
package/package.json
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "Permisos por defecto del stack:
|
|
2
|
+
"$comment": "Permisos por defecto del stack: cada bloque se escribe SOLO en config fresca o vacía; una config existente no se auto-expande jamás. OpenCode fresh default permite leer fuera del cwd, pero deja edit/bash en ask salvo allow explícito para lecturas seguras.",
|
|
3
3
|
"opencode": {
|
|
4
4
|
"permission": {
|
|
5
|
-
"edit": "
|
|
6
|
-
"read":
|
|
5
|
+
"edit": "ask",
|
|
6
|
+
"read": {
|
|
7
|
+
"*": "allow",
|
|
8
|
+
"*.env": "deny",
|
|
9
|
+
"*.env.*": "deny",
|
|
10
|
+
"*.env.example": "allow",
|
|
11
|
+
"*/.ssh/*": "deny",
|
|
12
|
+
"*/.aws/credentials": "deny",
|
|
13
|
+
"*/.npmrc": "deny",
|
|
14
|
+
"*/.git-credentials": "deny",
|
|
15
|
+
"*/id_rsa": "deny",
|
|
16
|
+
"*/id_ed25519": "deny",
|
|
17
|
+
"*.pem": "deny",
|
|
18
|
+
"*.key": "deny"
|
|
19
|
+
},
|
|
20
|
+
"external_directory": {
|
|
21
|
+
"*": "allow"
|
|
22
|
+
},
|
|
7
23
|
"glob": "allow",
|
|
8
24
|
"grep": "allow",
|
|
9
25
|
"list": "allow",
|
|
10
26
|
"lsp": "allow",
|
|
11
|
-
"webfetch": "
|
|
12
|
-
"websearch": "
|
|
27
|
+
"webfetch": "ask",
|
|
28
|
+
"websearch": "ask",
|
|
13
29
|
"bash": {
|
|
14
|
-
"*": "
|
|
30
|
+
"*": "ask",
|
|
31
|
+
"git diff*": "ask",
|
|
32
|
+
"git log*": "allow",
|
|
33
|
+
"git status*": "allow",
|
|
15
34
|
"rm *": "ask",
|
|
16
35
|
"del *": "ask",
|
|
17
36
|
"rmdir *": "ask",
|
|
@@ -25,13 +44,28 @@
|
|
|
25
44
|
},
|
|
26
45
|
"claude-code": {
|
|
27
46
|
"permissions": {
|
|
28
|
-
"allow": ["
|
|
29
|
-
"ask": ["Bash(rm:*)", "Bash(rmdir:*)", "Bash(del:*)", "Bash(git push --force:*)"],
|
|
30
|
-
"deny": [
|
|
47
|
+
"allow": ["Read", "Grep", "Glob"],
|
|
48
|
+
"ask": ["Bash", "Edit", "Write", "WebFetch", "WebSearch", "Bash(rm:*)", "Bash(rmdir:*)", "Bash(del:*)", "Bash(git push --force:*)"],
|
|
49
|
+
"deny": [
|
|
50
|
+
"Bash(format:*)",
|
|
51
|
+
"Bash(mkfs:*)",
|
|
52
|
+
"Bash(dd:*)",
|
|
53
|
+
"Bash(shred:*)",
|
|
54
|
+
"Read(//**/.env)",
|
|
55
|
+
"Read(//**/.env.*)",
|
|
56
|
+
"Read(//**/.ssh/**)",
|
|
57
|
+
"Read(//**/.aws/credentials)",
|
|
58
|
+
"Read(//**/.npmrc)",
|
|
59
|
+
"Read(//**/.git-credentials)",
|
|
60
|
+
"Read(//**/id_rsa)",
|
|
61
|
+
"Read(//**/id_ed25519)",
|
|
62
|
+
"Read(//**/*.pem)",
|
|
63
|
+
"Read(//**/*.key)"
|
|
64
|
+
]
|
|
31
65
|
}
|
|
32
66
|
},
|
|
33
67
|
"codex": {
|
|
34
68
|
"approval_policy": "on-request",
|
|
35
|
-
"
|
|
69
|
+
"default_permissions": "jorgex-read-anywhere"
|
|
36
70
|
}
|
|
37
71
|
}
|