@hasna/instructions 0.7.1 → 0.7.4
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 +47 -7
- package/dist/chunks/{apply-c3sd4agz.js → apply-1gyr8r0x.js} +3 -3
- package/dist/chunks/{apply-pnn7a3y7.js → apply-fyfzqc7s.js} +3 -3
- package/dist/chunks/{index-3djthcm6.js → index-27az1qb1.js} +28 -1
- package/dist/chunks/{index-r7nfef2g.js → index-6sbmg1vc.js} +3 -3
- package/dist/chunks/{index-pdpg8a44.js → index-axs3yftz.js} +2 -2
- package/dist/chunks/{index-aj66f6xr.js → index-dwagz53p.js} +92 -8
- package/dist/chunks/{index-6jncnnw7.js → index-enh4yv85.js} +274 -31
- package/dist/chunks/{index-ypcef3a2.js → index-n9arv47w.js} +2 -2
- package/dist/chunks/{index-n3fjspr0.js → index-preyvj8n.js} +28 -1
- package/dist/chunks/{index-jg8ptcwh.js → index-z27xp7fh.js} +2 -2
- package/dist/chunks/{local-0a9gja58.js → local-5dsm856v.js} +15 -4
- package/dist/chunks/{local-969ye538.js → local-yxsbs8x3.js} +15 -4
- package/dist/chunks/{sync-xtkbm5br.js → sync-6r1v8hd3.js} +4 -4
- package/dist/chunks/{sync-q5hvwq6e.js → sync-k3pab4s6.js} +4 -4
- package/dist/chunks/{template-wgnzdn7h.js → template-e4qrxs8p.js} +1 -1
- package/dist/chunks/{template-fsfxpe4p.js → template-nhn124zd.js} +1 -1
- package/dist/cli/index.js +1018 -584
- package/dist/data/config-store.d.ts +12 -4
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/db/configs.d.ts.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1264 -601
- package/dist/lib/asset-plan.d.ts +4 -1
- package/dist/lib/asset-plan.d.ts.map +1 -1
- package/dist/lib/codewith-shared-todos-storage-standard.d.ts.map +1 -1
- package/dist/lib/dangerous-operation-guard-standard.d.ts.map +1 -1
- package/dist/lib/global-agent-rules-standard.d.ts.map +1 -1
- package/dist/lib/global-source-coverage.d.ts +12 -7
- package/dist/lib/global-source-coverage.d.ts.map +1 -1
- package/dist/lib/harness-discovery.d.ts +52 -0
- package/dist/lib/harness-discovery.d.ts.map +1 -0
- package/dist/lib/instruction-graph.d.ts +1 -1
- package/dist/lib/instruction-graph.d.ts.map +1 -1
- package/dist/lib/instruction-source-policy.d.ts +6 -0
- package/dist/lib/instruction-source-policy.d.ts.map +1 -0
- package/dist/lib/machine.d.ts.map +1 -1
- package/dist/lib/managed-skill-runtimes.d.ts +12 -28
- package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
- package/dist/lib/platform-profiles.d.ts.map +1 -1
- package/dist/lib/project-dashboard-standard.d.ts.map +1 -1
- package/dist/lib/session-apply.d.ts +35 -0
- package/dist/lib/session-apply.d.ts.map +1 -1
- package/dist/lib/session-refresh.d.ts +30 -0
- package/dist/lib/session-refresh.d.ts.map +1 -0
- package/dist/lib/session-render.d.ts +41 -1
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/lib/transforms.d.ts +1 -0
- package/dist/lib/transforms.d.ts.map +1 -1
- package/dist/mcp/index.js +13 -12
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +172 -0
- package/dist/sdk/v1-client.d.ts +7 -1
- package/dist/sdk/v1-client.d.ts.map +1 -1
- package/dist/sdk/v1.generated.d.ts +26 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +199 -8
- package/dist/server/openapi.d.ts +150 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/cloud-store.d.ts.map +1 -1
- package/dist/types/index.d.ts +24 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
ProfileNotFoundError,
|
|
15
15
|
isTemplate,
|
|
16
16
|
renderTemplate,
|
|
17
|
-
renderTemplatePreview
|
|
18
|
-
|
|
17
|
+
renderTemplatePreview,
|
|
18
|
+
validateExpectedConfigVersion
|
|
19
|
+
} from "./index-preyvj8n.js";
|
|
19
20
|
import {
|
|
20
21
|
INSTRUCTIONS_LOCAL_OPT_IN_ENV_KEYS,
|
|
21
22
|
clientTransportEnvKeys,
|
|
@@ -77,6 +78,36 @@ function truncateMiddle(value, max = 80) {
|
|
|
77
78
|
return `${text.slice(0, head)}...${text.slice(text.length - tail)}`;
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
// src/lib/instruction-source-policy.ts
|
|
82
|
+
function isRetiredInstructionSource(config) {
|
|
83
|
+
return config.tags.some((tag) => tag === "retired-global-source" || tag === "retired-instruction-source");
|
|
84
|
+
}
|
|
85
|
+
function instructionSourceRejection(config) {
|
|
86
|
+
if (isRetiredInstructionSource(config) || config.tags.includes("config-only")) {
|
|
87
|
+
return "source is retired or explicitly configuration-only";
|
|
88
|
+
}
|
|
89
|
+
if (config.category !== "rules")
|
|
90
|
+
return `category ${config.category} is not an instruction source; classify reviewed prose as rules`;
|
|
91
|
+
if (config.format !== "markdown" && config.format !== "text")
|
|
92
|
+
return `format ${config.format} is not instruction prose`;
|
|
93
|
+
if (config.is_template)
|
|
94
|
+
return "unresolved templates must be rendered and reviewed before prompt injection";
|
|
95
|
+
if (!config.content.trim())
|
|
96
|
+
return "instruction source is empty";
|
|
97
|
+
if (config.content.includes("\x00"))
|
|
98
|
+
return "instruction source contains binary content";
|
|
99
|
+
const target = config.target_path?.split(/[\\/]/).pop() ?? "";
|
|
100
|
+
if (/\.(?:json|toml|yaml|yml|ini|sh|bash|zsh|fish|js|ts|py|rules)$/i.test(target)) {
|
|
101
|
+
return "target is an executable, provider policy, or settings file rather than a prompt";
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
function assertInstructionSource(config) {
|
|
106
|
+
const rejection = instructionSourceRejection(config);
|
|
107
|
+
if (rejection)
|
|
108
|
+
throw new Error(`Cannot inject ${config.slug}: ${rejection}.`);
|
|
109
|
+
}
|
|
110
|
+
|
|
80
111
|
// src/lib/global-agent-rules-standard.ts
|
|
81
112
|
import { createHash as createHash7 } from "crypto";
|
|
82
113
|
|
|
@@ -186,17 +217,18 @@ async function ensureCodewithSharedTodosStorageStandardConfig(store = resolveCon
|
|
|
186
217
|
let config;
|
|
187
218
|
try {
|
|
188
219
|
const existing = await store.getConfig(CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG);
|
|
220
|
+
if (isRetiredInstructionSource(existing))
|
|
221
|
+
return existing;
|
|
189
222
|
if (existing.content !== input.content || existing.description !== input.description || existing.category !== input.category || existing.agent !== input.agent || existing.format !== input.format || existing.kind !== input.kind || JSON.stringify(existing.tags) !== JSON.stringify(input.tags)) {
|
|
190
223
|
config = await store.updateConfig(existing.id, input);
|
|
191
224
|
} else {
|
|
192
225
|
config = existing;
|
|
193
226
|
}
|
|
194
|
-
} catch {
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (!(error instanceof ConfigNotFoundError))
|
|
229
|
+
throw error;
|
|
195
230
|
config = await store.createConfig(input);
|
|
196
231
|
}
|
|
197
|
-
for (const profile of await store.listProfiles()) {
|
|
198
|
-
await store.addConfigToProfile(profile.id, config.id);
|
|
199
|
-
}
|
|
200
232
|
return config;
|
|
201
233
|
}
|
|
202
234
|
|
|
@@ -7373,6 +7405,9 @@ function buildCodexAgentsMd(source, context = {}) {
|
|
|
7373
7405
|
function buildOpenCodeAgentsMd(source, context = {}) {
|
|
7374
7406
|
return flattenWithRules(source, context);
|
|
7375
7407
|
}
|
|
7408
|
+
function buildSumiAgentsMd(source, context = {}) {
|
|
7409
|
+
return flattenWithRules(source, context);
|
|
7410
|
+
}
|
|
7376
7411
|
function buildCursorMdc(source) {
|
|
7377
7412
|
const stem = source.target_path ? basename2(source.target_path, extname(source.target_path)) : source.slug;
|
|
7378
7413
|
const description = source.name || stem;
|
|
@@ -7401,6 +7436,8 @@ function applyTransform(source, output, context = {}) {
|
|
|
7401
7436
|
return buildCodexAgentsMd(source, context);
|
|
7402
7437
|
case "opencode-flat":
|
|
7403
7438
|
return buildOpenCodeAgentsMd(source, context);
|
|
7439
|
+
case "sumi-flat":
|
|
7440
|
+
return buildSumiAgentsMd(source, context);
|
|
7404
7441
|
case "cursor-mdc":
|
|
7405
7442
|
return buildCursorMdc(source);
|
|
7406
7443
|
case "skill-neutral":
|
|
@@ -7473,6 +7510,7 @@ function assetCapability(provider, surface, kind, support, strategies, note, pro
|
|
|
7473
7510
|
var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
|
|
7474
7511
|
assetCapability("claude", "code", "skill", "supported", ["emit-file"], "Claude Code project or profile skill files."),
|
|
7475
7512
|
assetCapability("claude", "code", "workflow", "supported", ["emit-file"], "Claude Code command and workflow files."),
|
|
7513
|
+
assetCapability("claude", "code", "custom-agent", "supported", ["emit-file"], "Claude Code Markdown subagents with native frontmatter in agents/.", ">=2.1.276 <3.0.0"),
|
|
7476
7514
|
assetCapability("claude", "code", "hook", "supported", ["emit-file"], "Claude Code hook configuration fragments."),
|
|
7477
7515
|
assetCapability("claude", "code", "plugin", "conditional", ["install-marketplace"], "Claude marketplace installation requires an explicit installer."),
|
|
7478
7516
|
assetCapability("codex", "cli", "skill", "supported", ["emit-file"], "Codex skill bundle files."),
|
|
@@ -7483,6 +7521,7 @@ var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
|
|
|
7483
7521
|
assetCapability("opencode", "cli", "workflow", "supported", ["emit-file"], "OpenCode command/workflow files."),
|
|
7484
7522
|
assetCapability("opencode", "cli", "plugin", "supported", ["emit-file"], "OpenCode local plugin modules."),
|
|
7485
7523
|
assetCapability("opencode", "cli", "custom-agent", "supported", ["emit-file"], "OpenCode custom agent files."),
|
|
7524
|
+
assetCapability("sumi", "cli", "custom-agent", "supported", ["emit-file"], "Sumi Markdown agent definitions in its explicit resolved config or project directory.", ">=0.2.22 <0.3.0"),
|
|
7486
7525
|
assetCapability("codewith", "cli", "skill", "supported", ["emit-file"], "Codewith skill bundle files."),
|
|
7487
7526
|
assetCapability("codewith", "cli", "plugin", "conditional", ["install-local", "install-marketplace"], "Codewith plugin installation requires an explicit installer."),
|
|
7488
7527
|
assetCapability("aicopilot", "cli", "skill", "supported", ["emit-file"], "AICopilot discovered skill files."),
|
|
@@ -7515,6 +7554,7 @@ var DEFAULT_ASSET_SURFACES = Object.freeze({
|
|
|
7515
7554
|
codex: "cli",
|
|
7516
7555
|
cursor: "ide",
|
|
7517
7556
|
opencode: "cli",
|
|
7557
|
+
sumi: "cli",
|
|
7518
7558
|
codewith: "cli",
|
|
7519
7559
|
qwen: "cli",
|
|
7520
7560
|
aicopilot: "cli",
|
|
@@ -7585,6 +7625,10 @@ function normalizeProfileAssetBinding(value) {
|
|
|
7585
7625
|
const rollback = record["rollback"];
|
|
7586
7626
|
if (!ASSET_ROLLBACK_POLICIES.includes(rollback))
|
|
7587
7627
|
throw new Error(`Invalid asset rollback policy: ${String(rollback)}`);
|
|
7628
|
+
const nativeAgent = record["nativeAgent"] === undefined ? undefined : normalizeNativeAgentMetadata(record["nativeAgent"]);
|
|
7629
|
+
if (nativeAgent && (kind !== "custom-agent" || strategy !== "emit-file" || !["claude", "sumi", "opencode"].includes(provider))) {
|
|
7630
|
+
throw new Error("nativeAgent metadata requires a supported emitted custom-agent definition.");
|
|
7631
|
+
}
|
|
7588
7632
|
return {
|
|
7589
7633
|
schema: PROFILE_ASSET_BINDING_SCHEMA,
|
|
7590
7634
|
assetKey,
|
|
@@ -7604,6 +7648,7 @@ function normalizeProfileAssetBinding(value) {
|
|
|
7604
7648
|
root,
|
|
7605
7649
|
relativePath: nonEmptyString(destinationRecord["relativePath"], "destination.relativePath")
|
|
7606
7650
|
},
|
|
7651
|
+
...nativeAgent ? { nativeAgent } : {},
|
|
7607
7652
|
uninstall,
|
|
7608
7653
|
rollback
|
|
7609
7654
|
};
|
|
@@ -7679,6 +7724,7 @@ function compileAssetPlan(input) {
|
|
|
7679
7724
|
allowed: binding.source.allowed
|
|
7680
7725
|
},
|
|
7681
7726
|
destination: binding.destination,
|
|
7727
|
+
...binding.nativeAgent ? { nativeAgent: binding.nativeAgent } : {},
|
|
7682
7728
|
support,
|
|
7683
7729
|
action,
|
|
7684
7730
|
mutationMode: input.mode,
|
|
@@ -7743,6 +7789,18 @@ function validateAssetSourceAndDestination(bundle, binding, diagnostics) {
|
|
|
7743
7789
|
pathSafe = false;
|
|
7744
7790
|
diagnostics.push(diagnostic("error", "ASSET_DESTINATION_UNSAFE", binding.assetKey, error.message));
|
|
7745
7791
|
}
|
|
7792
|
+
if (pathSafe && binding.kind === "custom-agent" && binding.destination.strategy === "emit-file" && (binding.selector.provider === "claude" || binding.selector.provider === "sumi" || binding.nativeAgent) && (binding.destination.root !== "target-home" || !/^agents\/[A-Za-z0-9][A-Za-z0-9_-]*\.md$/.test(safeRelativePath(binding.destination.relativePath)))) {
|
|
7793
|
+
pathSafe = false;
|
|
7794
|
+
diagnostics.push(diagnostic("error", "ASSET_CUSTOM_AGENT_DESTINATION_UNSUPPORTED", binding.assetKey, "Native custom-agent definitions require agents/<name>.md beneath an explicit target-home."));
|
|
7795
|
+
}
|
|
7796
|
+
if (binding.nativeAgent) {
|
|
7797
|
+
if (posix.basename(binding.destination.relativePath, ".md") !== binding.nativeAgent.name) {
|
|
7798
|
+
diagnostics.push(diagnostic("error", "ASSET_NATIVE_AGENT_NAME_MISMATCH", binding.assetKey, "Native role name must match its destination filename."));
|
|
7799
|
+
}
|
|
7800
|
+
if (/^\uFEFF?---[ \t]*\r?\n/.test(bundle.content)) {
|
|
7801
|
+
diagnostics.push(diagnostic("error", "ASSET_NATIVE_AGENT_DOUBLE_HEADER", binding.assetKey, "Canonical role prose must not already contain frontmatter when nativeAgent metadata is supplied."));
|
|
7802
|
+
}
|
|
7803
|
+
}
|
|
7746
7804
|
const expectedLocator = bundle.locator;
|
|
7747
7805
|
if (!binding.source.immutable || binding.source.locator !== expectedLocator) {
|
|
7748
7806
|
diagnostics.push(diagnostic("error", "ASSET_SOURCE_MUTABLE_OR_UNPINNED", binding.assetKey, `Asset source must be pinned to ${expectedLocator}.`));
|
|
@@ -7798,6 +7856,72 @@ function safeRelativePath(value) {
|
|
|
7798
7856
|
}
|
|
7799
7857
|
return normalized;
|
|
7800
7858
|
}
|
|
7859
|
+
function normalizeNativeAgentMetadata(value) {
|
|
7860
|
+
const record = objectRecord(value, "nativeAgent");
|
|
7861
|
+
if (Object.keys(record).some((key) => !["name", "description", "frontmatter"].includes(key)))
|
|
7862
|
+
throw new Error("Unknown nativeAgent metadata field.");
|
|
7863
|
+
const name = nonEmptyString(record["name"], "nativeAgent.name");
|
|
7864
|
+
const description = nonEmptyString(record["description"], "nativeAgent.description");
|
|
7865
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(name) || name.length > 128)
|
|
7866
|
+
throw new Error("Invalid nativeAgent.name.");
|
|
7867
|
+
if (description.length > 4096 || /[\r\n\0]/.test(description))
|
|
7868
|
+
throw new Error("Invalid nativeAgent.description.");
|
|
7869
|
+
if (record["frontmatter"] === undefined)
|
|
7870
|
+
return { name, description };
|
|
7871
|
+
const frontmatter = record["frontmatter"];
|
|
7872
|
+
if (typeof frontmatter !== "string" || frontmatter.length > 16384 || frontmatter.includes("\x00"))
|
|
7873
|
+
throw new Error("Invalid nativeAgent.frontmatter.");
|
|
7874
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n$/.exec(frontmatter);
|
|
7875
|
+
if (!match)
|
|
7876
|
+
throw new Error("nativeAgent.frontmatter requires one complete newline-terminated YAML header.");
|
|
7877
|
+
const scalar = (raw) => {
|
|
7878
|
+
if (raw.startsWith('"')) {
|
|
7879
|
+
try {
|
|
7880
|
+
const parsed = JSON.parse(raw);
|
|
7881
|
+
return typeof parsed === "string" ? parsed : undefined;
|
|
7882
|
+
} catch {
|
|
7883
|
+
return;
|
|
7884
|
+
}
|
|
7885
|
+
}
|
|
7886
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9 _.,:;()/?@+-]*$/.test(raw) || /:(?:\s|$)/.test(raw))
|
|
7887
|
+
return;
|
|
7888
|
+
if (/^(?:true|yes|on|y)$/i.test(raw))
|
|
7889
|
+
return true;
|
|
7890
|
+
if (/^(?:false|no|off|n)$/i.test(raw))
|
|
7891
|
+
return false;
|
|
7892
|
+
if (/^null$/i.test(raw))
|
|
7893
|
+
return null;
|
|
7894
|
+
if (/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(raw))
|
|
7895
|
+
return Number(raw);
|
|
7896
|
+
if (/^[0-9]/.test(raw))
|
|
7897
|
+
return;
|
|
7898
|
+
return raw;
|
|
7899
|
+
};
|
|
7900
|
+
const fields = new Map;
|
|
7901
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
7902
|
+
if (!line.trim() || line.startsWith("#"))
|
|
7903
|
+
continue;
|
|
7904
|
+
const field = /^([A-Za-z][A-Za-z0-9_-]*):[ \t]+(.+)$/.exec(line);
|
|
7905
|
+
if (!field || fields.has(field[1]) || scalar(field[2]) === undefined)
|
|
7906
|
+
throw new Error("nativeAgent.frontmatter requires unambiguous, unique flat scalar fields.");
|
|
7907
|
+
fields.set(field[1], scalar(field[2]));
|
|
7908
|
+
}
|
|
7909
|
+
if (fields.get("name") !== name || fields.get("description") !== description)
|
|
7910
|
+
throw new Error("nativeAgent.frontmatter name and description must match explicit metadata.");
|
|
7911
|
+
return { name, description, frontmatter };
|
|
7912
|
+
}
|
|
7913
|
+
function renderNativeAgentContent(content, metadata) {
|
|
7914
|
+
if (!metadata)
|
|
7915
|
+
return content;
|
|
7916
|
+
const value = normalizeNativeAgentMetadata(metadata);
|
|
7917
|
+
if (/^\uFEFF?---[ \t]*\r?\n/.test(content))
|
|
7918
|
+
throw new Error("Canonical role prose already contains frontmatter.");
|
|
7919
|
+
return (value.frontmatter ?? `---
|
|
7920
|
+
name: ${JSON.stringify(value.name)}
|
|
7921
|
+
description: ${JSON.stringify(value.description)}
|
|
7922
|
+
---
|
|
7923
|
+
`) + content;
|
|
7924
|
+
}
|
|
7801
7925
|
function diagnostic(severity, code, assetKey, message) {
|
|
7802
7926
|
return { severity, code, assetKey, message };
|
|
7803
7927
|
}
|
|
@@ -8178,6 +8302,7 @@ var SESSION_RENDER_TOOLS = [
|
|
|
8178
8302
|
"codex",
|
|
8179
8303
|
"cursor",
|
|
8180
8304
|
"opencode",
|
|
8305
|
+
"sumi",
|
|
8181
8306
|
"codewith",
|
|
8182
8307
|
"qwen",
|
|
8183
8308
|
"aicopilot",
|
|
@@ -8266,6 +8391,15 @@ var SESSION_TOOL_ADAPTERS = {
|
|
|
8266
8391
|
description: "OpenCode AGENTS.md plus opencode.json instructions pointing at managed fragments.",
|
|
8267
8392
|
providerSurface: "legacy-dual"
|
|
8268
8393
|
},
|
|
8394
|
+
sumi: {
|
|
8395
|
+
tool: "sumi",
|
|
8396
|
+
mode: "flattened-markdown",
|
|
8397
|
+
indexFile: "AGENTS.md",
|
|
8398
|
+
managedDir: SESSION_RENDER_INSTRUCTIONS_MANAGED_DIR,
|
|
8399
|
+
envVar: "SUMI_CONFIG_DIR",
|
|
8400
|
+
nativeImports: false,
|
|
8401
|
+
description: "Sumi native AGENTS.md in the explicit resolved config directory or project root."
|
|
8402
|
+
},
|
|
8269
8403
|
aicopilot: {
|
|
8270
8404
|
tool: "aicopilot",
|
|
8271
8405
|
mode: "flattened-markdown",
|
|
@@ -8550,9 +8684,19 @@ function skippedSource(source, reason) {
|
|
|
8550
8684
|
};
|
|
8551
8685
|
}
|
|
8552
8686
|
function normalizeSources(sources, tool, allowEmptySources) {
|
|
8553
|
-
const
|
|
8687
|
+
const providerSkipped = [];
|
|
8688
|
+
const normalized = sources.flatMap((source, index) => {
|
|
8554
8689
|
if (!source.id.trim())
|
|
8555
8690
|
throw new Error("Session instruction source id is required.");
|
|
8691
|
+
if (source.targetProviders?.length && !providerTargetsTool(source.targetProviders, tool)) {
|
|
8692
|
+
providerSkipped.push({
|
|
8693
|
+
id: source.id,
|
|
8694
|
+
label: source.label ?? source.id,
|
|
8695
|
+
targetProviders: source.targetProviders,
|
|
8696
|
+
reason: "instruction source targets a different provider"
|
|
8697
|
+
});
|
|
8698
|
+
return [];
|
|
8699
|
+
}
|
|
8556
8700
|
const floored = applyAgentOperatingRulesFloor(source, source.content ?? "");
|
|
8557
8701
|
const content = filterProviderOnlyBlocks(floored.content, tool);
|
|
8558
8702
|
const normalized2 = {
|
|
@@ -8571,7 +8715,7 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
8571
8715
|
if (!allowEmptySources && !normalized2.content.trim() && normalized2.resolvedRules.length === 0 && !hasPathReferences) {
|
|
8572
8716
|
throw new Error(`Session instruction source "${source.id}" is empty. Pass --allow-empty-sources only for explicit empty renders.`);
|
|
8573
8717
|
}
|
|
8574
|
-
return normalized2;
|
|
8718
|
+
return [normalized2];
|
|
8575
8719
|
});
|
|
8576
8720
|
const originalOrder = [...normalized].sort(compareSessionInstructionSources);
|
|
8577
8721
|
const deduplicated = deduplicateSemanticPolicySources(normalized);
|
|
@@ -8579,7 +8723,7 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
8579
8723
|
validateTargetedReplacementSources(originalOrder, ordered, deduplicated.skipped, tool);
|
|
8580
8724
|
rejectDuplicateSourceSlugs(ordered);
|
|
8581
8725
|
rejectDuplicateRulePaths(ordered);
|
|
8582
|
-
return { sources: ordered, skipped: deduplicated.skipped };
|
|
8726
|
+
return { sources: ordered, skipped: [...providerSkipped, ...deduplicated.skipped] };
|
|
8583
8727
|
}
|
|
8584
8728
|
function compareSessionInstructionSources(a, b) {
|
|
8585
8729
|
return SESSION_LAYER_RANK[a.resolvedLayer] - SESSION_LAYER_RANK[b.resolvedLayer] || a.resolvedOrder - b.resolvedOrder || a.id.localeCompare(b.id);
|
|
@@ -9008,7 +9152,7 @@ function buildCursorRuleFiles(targetHome, adapter, sources) {
|
|
|
9008
9152
|
return [sourceFile, ...ruleFiles];
|
|
9009
9153
|
});
|
|
9010
9154
|
}
|
|
9011
|
-
function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig) {
|
|
9155
|
+
function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig, projectRoot) {
|
|
9012
9156
|
const surface = adapter.providerSurface ?? "legacy-dual";
|
|
9013
9157
|
const fragments = sources.flatMap((source, index) => [
|
|
9014
9158
|
makeFile(targetHome, fragmentPath(adapter, index, source), "fragment", sectionForSource(source), [source.id]),
|
|
@@ -9028,13 +9172,13 @@ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfi
|
|
|
9028
9172
|
]);
|
|
9029
9173
|
const existingConfigPath = joinTarget(targetHome, adapter.configFile);
|
|
9030
9174
|
const selectedConfig = existsSync4(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
|
|
9031
|
-
const preservedInstructions = normalizeOpenCodeInstructions(selectedConfig["instructions"]).filter((path) => !pathIsManagedOpenCodeInstruction(path, adapter.managedDir));
|
|
9175
|
+
const preservedInstructions = normalizeOpenCodeInstructions(selectedConfig["instructions"]).filter((path) => !pathIsManagedOpenCodeInstruction(path, adapter.managedDir, targetHome, projectRoot));
|
|
9032
9176
|
const config = {
|
|
9033
9177
|
...selectedConfig,
|
|
9034
9178
|
$schema: typeof selectedConfig["$schema"] === "string" ? selectedConfig["$schema"] : "https://opencode.ai/config.json",
|
|
9035
9179
|
instructions: [
|
|
9036
9180
|
...preservedInstructions,
|
|
9037
|
-
...fragments.map((file) => file.
|
|
9181
|
+
...fragments.map((file) => file.path)
|
|
9038
9182
|
]
|
|
9039
9183
|
};
|
|
9040
9184
|
const configSourceIds = [
|
|
@@ -9077,9 +9221,62 @@ function normalizeOpenCodeInstructions(value) {
|
|
|
9077
9221
|
}
|
|
9078
9222
|
return value;
|
|
9079
9223
|
}
|
|
9080
|
-
function pathIsManagedOpenCodeInstruction(
|
|
9081
|
-
const
|
|
9082
|
-
|
|
9224
|
+
function pathIsManagedOpenCodeInstruction(reference, managedDir, targetHome, projectRoot) {
|
|
9225
|
+
const normalizedManagedDir = posix2.normalize(managedDir.replaceAll("\\", "/"));
|
|
9226
|
+
const candidates = canonicalOpenCodeInstructionPaths(reference, targetHome, projectRoot);
|
|
9227
|
+
return candidates.some((candidate) => candidate === normalizedManagedDir || candidate.endsWith(`/${normalizedManagedDir}`) || candidate.includes(`/${normalizedManagedDir}/`));
|
|
9228
|
+
}
|
|
9229
|
+
function canonicalOpenCodeInstructionPaths(reference, targetHome, projectRoot) {
|
|
9230
|
+
const portable = decodeOpenCodePathEscapes(reference.replaceAll("\\", "/")).replaceAll("\\", "/");
|
|
9231
|
+
if (portable.includes("\x00")) {
|
|
9232
|
+
throw new Error("OpenCode config instruction references cannot contain NUL bytes.");
|
|
9233
|
+
}
|
|
9234
|
+
const windowsAbsolute = /^[A-Za-z]:\//.test(portable);
|
|
9235
|
+
const uriScheme = windowsAbsolute ? null : /^([A-Za-z][A-Za-z0-9+.-]*):/.exec(portable)?.[1]?.toLowerCase();
|
|
9236
|
+
if (uriScheme && uriScheme !== "file")
|
|
9237
|
+
return [];
|
|
9238
|
+
if (uriScheme === "file") {
|
|
9239
|
+
const fileReference = reference.replaceAll("\\", "/");
|
|
9240
|
+
if (!/^file:\/\//i.test(fileReference)) {
|
|
9241
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9242
|
+
}
|
|
9243
|
+
let url;
|
|
9244
|
+
try {
|
|
9245
|
+
url = new URL(fileReference);
|
|
9246
|
+
} catch {
|
|
9247
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9248
|
+
}
|
|
9249
|
+
if (url.protocol !== "file:" || url.username || url.password || url.port || url.search || url.hash) {
|
|
9250
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9251
|
+
}
|
|
9252
|
+
const pathname = decodeOpenCodePathEscapes(url.pathname);
|
|
9253
|
+
if (pathname.includes("\x00")) {
|
|
9254
|
+
throw new Error("OpenCode config instruction references cannot contain NUL bytes.");
|
|
9255
|
+
}
|
|
9256
|
+
const host = url.hostname && url.hostname !== "localhost" ? `//${url.hostname}` : "";
|
|
9257
|
+
return [normalizePortableOpenCodePath(`${host}${pathname}`)];
|
|
9258
|
+
}
|
|
9259
|
+
if (posix2.isAbsolute(portable) || windowsAbsolute || portable.startsWith("//")) {
|
|
9260
|
+
return [normalizePortableOpenCodePath(portable)];
|
|
9261
|
+
}
|
|
9262
|
+
const roots = [
|
|
9263
|
+
...projectRoot ? [resolveSessionPath(projectRoot)] : [],
|
|
9264
|
+
resolveSessionPath(targetHome)
|
|
9265
|
+
];
|
|
9266
|
+
return [...new Set(roots.map((root) => normalizePortableOpenCodePath(posix2.join(root.replaceAll("\\", "/"), portable))))];
|
|
9267
|
+
}
|
|
9268
|
+
function decodeOpenCodePathEscapes(value) {
|
|
9269
|
+
return value.replace(/(?:%[a-fA-F0-9]{2})+/g, (encoded) => {
|
|
9270
|
+
try {
|
|
9271
|
+
return decodeURIComponent(encoded);
|
|
9272
|
+
} catch {
|
|
9273
|
+
return encoded;
|
|
9274
|
+
}
|
|
9275
|
+
});
|
|
9276
|
+
}
|
|
9277
|
+
function normalizePortableOpenCodePath(value) {
|
|
9278
|
+
const normalized = posix2.normalize(value.replaceAll("\\", "/"));
|
|
9279
|
+
return normalized.startsWith("//") ? `/${normalized.replace(/^\/+/u, "")}` : normalized;
|
|
9083
9280
|
}
|
|
9084
9281
|
function buildAntigravityRuleFiles(targetHome, adapter, sources) {
|
|
9085
9282
|
return sources.flatMap((source, index) => {
|
|
@@ -9133,7 +9330,7 @@ function makeAntigravityRuleFile(targetHome, relativePath, content, sourceIds) {
|
|
|
9133
9330
|
}
|
|
9134
9331
|
return file;
|
|
9135
9332
|
}
|
|
9136
|
-
function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion) {
|
|
9333
|
+
function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion, projectRoot) {
|
|
9137
9334
|
switch (adapter.mode) {
|
|
9138
9335
|
case "native-imports":
|
|
9139
9336
|
return buildNativeImportFiles(targetHome, adapter, profile, sources, providerVersion);
|
|
@@ -9142,7 +9339,7 @@ function buildFiles(targetHome, adapter, profile, sources, providerConfig, provi
|
|
|
9142
9339
|
case "cursor-mdc":
|
|
9143
9340
|
return buildCursorRuleFiles(targetHome, adapter, sources);
|
|
9144
9341
|
case "opencode-instructions":
|
|
9145
|
-
return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig);
|
|
9342
|
+
return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig, projectRoot);
|
|
9146
9343
|
case "antigravity-rules":
|
|
9147
9344
|
return buildAntigravityRuleFiles(targetHome, adapter, sources);
|
|
9148
9345
|
case "provider-rules":
|
|
@@ -9171,12 +9368,13 @@ function buildAssetFiles(input, targetHome, blocked) {
|
|
|
9171
9368
|
if (!relativePath || relativePath === ".." || relativePath.startsWith("../") || isAbsolute3(relativePath)) {
|
|
9172
9369
|
throw new Error(`Asset ${item.assetKey} is outside the session snapshot root; use a project-scoped session plan for atomic application.`);
|
|
9173
9370
|
}
|
|
9371
|
+
const renderedContent = renderNativeAgentContent(content, item.nativeAgent);
|
|
9174
9372
|
return {
|
|
9175
9373
|
path,
|
|
9176
9374
|
relativePath: assertSafeRelativePath(relativePath),
|
|
9177
9375
|
role: "asset",
|
|
9178
|
-
content,
|
|
9179
|
-
sha256: sha2565(
|
|
9376
|
+
content: renderedContent,
|
|
9377
|
+
sha256: sha2565(renderedContent),
|
|
9180
9378
|
sourceIds: [item.sourceConfigId, item.assetId]
|
|
9181
9379
|
};
|
|
9182
9380
|
});
|
|
@@ -9185,6 +9383,11 @@ function isNativeProfileSessionTarget(input) {
|
|
|
9185
9383
|
return (input.tool === "grok" || input.tool === "devin") && Boolean(input.targetHome?.trim()) && !input.projectRoot;
|
|
9186
9384
|
}
|
|
9187
9385
|
function adapterFor(input) {
|
|
9386
|
+
if (input.tool === "sumi" && input.projectRoot) {
|
|
9387
|
+
if (input.providerSurface)
|
|
9388
|
+
throw new Error(`Provider surface ${input.providerSurface} is not valid for Sumi.`);
|
|
9389
|
+
return Object.freeze({ ...SESSION_TOOL_ADAPTERS.sumi, projectScoped: true, envVar: undefined });
|
|
9390
|
+
}
|
|
9188
9391
|
if (input.tool === "opencode" && input.providerSurface) {
|
|
9189
9392
|
if (input.providerSurface !== "opencode-config-instructions" && input.providerSurface !== "opencode-agents-md") {
|
|
9190
9393
|
throw new Error(`Provider surface ${input.providerSurface} is not valid for OpenCode.`);
|
|
@@ -9226,7 +9429,7 @@ function adapterFor(input) {
|
|
|
9226
9429
|
}
|
|
9227
9430
|
if (input.tool !== "codewith")
|
|
9228
9431
|
return SESSION_TOOL_ADAPTERS[input.tool];
|
|
9229
|
-
const gatedNativeImports = input.codewithNativeImports
|
|
9432
|
+
const gatedNativeImports = input.codewithNativeImports ?? (process.env[CODEWITH_NATIVE_IMPORTS_ENV] === "1" || process.env[CODEWITH_NATIVE_IMPORTS_ENV] === "true");
|
|
9230
9433
|
return gatedNativeImports ? CODEWITH_NATIVE_ADAPTER : CODEWITH_FLATTENED_ADAPTER;
|
|
9231
9434
|
}
|
|
9232
9435
|
function getHomeDir() {
|
|
@@ -9277,6 +9480,13 @@ function assertSafeTargetRoot(targetHome) {
|
|
|
9277
9480
|
return normalized;
|
|
9278
9481
|
}
|
|
9279
9482
|
function resolveRenderTarget(input, adapter) {
|
|
9483
|
+
if (input.tool === "sumi" && !input.projectRoot && !input.targetHome?.trim()) {
|
|
9484
|
+
return {
|
|
9485
|
+
targetHome: defaultTargetHome(input.tool, input.profile, input.sessionId),
|
|
9486
|
+
targetKind: "blocked",
|
|
9487
|
+
blockers: ["Sumi requires --target-home from `sumi debug paths config`, or --project-root for repository AGENTS.md."]
|
|
9488
|
+
};
|
|
9489
|
+
}
|
|
9280
9490
|
if (adapter.projectScoped) {
|
|
9281
9491
|
if (!input.projectRoot) {
|
|
9282
9492
|
const label = input.tool === "cursor" ? "Cursor rules" : input.tool === "antigravity" ? "Antigravity rules" : `${adapter.description.split(".")[0]} files`;
|
|
@@ -9343,7 +9553,7 @@ function resolveSessionTargetOwnership(input, target) {
|
|
|
9343
9553
|
tool: input.tool,
|
|
9344
9554
|
profile: input.profile,
|
|
9345
9555
|
targetHome: target.targetHome,
|
|
9346
|
-
projectRoot: null,
|
|
9556
|
+
projectRoot: input.tool === "opencode" && input.projectRoot ? resolveSessionPath(input.projectRoot) : null,
|
|
9347
9557
|
ownedBy: "open-configs",
|
|
9348
9558
|
canonicalOwner: "instructions",
|
|
9349
9559
|
writer: {
|
|
@@ -9378,6 +9588,14 @@ function planSessionRender(input) {
|
|
|
9378
9588
|
const normalized = normalizeSources(input.sources, input.tool, allowEmptySources);
|
|
9379
9589
|
const composed = composeSources(normalized.sources, input.tool);
|
|
9380
9590
|
const orderedSources = composed.sources;
|
|
9591
|
+
if (input.tool === "sumi") {
|
|
9592
|
+
for (const source of orderedSources) {
|
|
9593
|
+
const activation = source.metadata?.["activation"];
|
|
9594
|
+
if (source.globs?.length || source.resolvedRules.some((rule) => rule.globs?.length) || activation?.mode && activation.mode !== "always") {
|
|
9595
|
+
throw new Error(`Sumi AGENTS.md cannot preserve conditional activation for source ${source.id}; compile a profile with an explicit supported fallback.`);
|
|
9596
|
+
}
|
|
9597
|
+
}
|
|
9598
|
+
}
|
|
9381
9599
|
const skippedSources = [
|
|
9382
9600
|
...input.skippedSources ?? [],
|
|
9383
9601
|
...normalized.skipped,
|
|
@@ -9396,7 +9614,7 @@ function planSessionRender(input) {
|
|
|
9396
9614
|
if (input.providerConfig && input.tool !== "opencode") {
|
|
9397
9615
|
throw new Error("Provider base config is supported only for OpenCode session renders.");
|
|
9398
9616
|
}
|
|
9399
|
-
const baseFiles = blocked ? [] : buildFiles(targetHome, adapter, input.profile, orderedSources, input.providerConfig, input.provider_version);
|
|
9617
|
+
const baseFiles = blocked ? [] : buildFiles(targetHome, adapter, input.profile, orderedSources, input.providerConfig, input.provider_version, input.projectRoot);
|
|
9400
9618
|
const projectContext = blocked ? null : composeProjectContextSessionRender({
|
|
9401
9619
|
tool: input.tool,
|
|
9402
9620
|
adapter_mode: adapter.mode,
|
|
@@ -9421,6 +9639,7 @@ function planSessionRender(input) {
|
|
|
9421
9639
|
adapterMode: adapter.mode,
|
|
9422
9640
|
profile: input.profile,
|
|
9423
9641
|
sessionId: input.sessionId ?? null,
|
|
9642
|
+
...input.refreshSelector ? { refreshSelector: input.refreshSelector } : {},
|
|
9424
9643
|
targetHome,
|
|
9425
9644
|
targetKind,
|
|
9426
9645
|
targetOwner,
|
|
@@ -9496,6 +9715,7 @@ function planSessionRender(input) {
|
|
|
9496
9715
|
mutationMode: item.mutationMode,
|
|
9497
9716
|
destination: item.destination,
|
|
9498
9717
|
digest: item.source.digest,
|
|
9718
|
+
...item.nativeAgent ? { nativeAgent: item.nativeAgent } : {},
|
|
9499
9719
|
exactOnceKey: item.exactOnceKey
|
|
9500
9720
|
}))
|
|
9501
9721
|
}
|
|
@@ -9933,6 +10153,7 @@ var DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
|
|
|
9933
10153
|
codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
|
|
9934
10154
|
cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
|
|
9935
10155
|
opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
|
|
10156
|
+
sumi: capability("sumi", ">=0.2.22 <0.3.0", "flattened", "AGENTS.md"),
|
|
9936
10157
|
codewith: capability("codewith", ">=0.1.0", "flattened", "CODEWITH.md"),
|
|
9937
10158
|
qwen: capability("qwen", ">=0.1.0", "flattened", "QWEN.md"),
|
|
9938
10159
|
aicopilot: capability("aicopilot", ">=0.1.0", "flattened", "AICOPILOT.md"),
|
|
@@ -10155,12 +10376,22 @@ function compileInstructionGraph(input) {
|
|
|
10155
10376
|
const selector = binding.providers?.find((entry) => entry.provider === input.context.provider || entry.provider === "global");
|
|
10156
10377
|
if (binding.providers?.length && !selector)
|
|
10157
10378
|
continue;
|
|
10379
|
+
const output = config.outputs.find((entry) => entry.agent === input.context.provider);
|
|
10380
|
+
if (!binding.providers?.length && config.agent !== "global" && config.agent !== input.context.provider && !output) {
|
|
10381
|
+
diagnostics.push({ severity: "info", code: "SOURCE_PROVIDER_NOT_SELECTED", config_id: configId, message: `${config.slug} targets ${config.agent}, not ${input.context.provider}.` });
|
|
10382
|
+
continue;
|
|
10383
|
+
}
|
|
10158
10384
|
if (selector?.version_range && !providerVersionSatisfies(input.context.provider_version, selector.version_range)) {
|
|
10159
10385
|
diagnostics.push({ severity: binding.required ? "error" : "warning", code: "PROVIDER_SELECTOR_VERSION_MISMATCH", config_id: configId, message: `${config.slug} requires ${input.context.provider} ${selector.version_range}; current version is ${input.context.provider_version}.` });
|
|
10160
10386
|
continue;
|
|
10161
10387
|
}
|
|
10162
10388
|
if (!activationMatches(binding.activation, config, input.context))
|
|
10163
10389
|
continue;
|
|
10390
|
+
const rejection = instructionSourceRejection(config);
|
|
10391
|
+
if (rejection) {
|
|
10392
|
+
diagnostics.push({ severity: !binding.required && binding.fallback === "omit" ? "warning" : "error", code: "SOURCE_NOT_INSTRUCTION", config_id: configId, message: `${config.slug}: ${rejection}.` });
|
|
10393
|
+
continue;
|
|
10394
|
+
}
|
|
10164
10395
|
if (capability2.activation_modes.includes(binding.activation.mode)) {
|
|
10165
10396
|
selected.add(configId);
|
|
10166
10397
|
effective.set(configId, binding.activation);
|
|
@@ -10235,7 +10466,9 @@ function compileInstructionGraph(input) {
|
|
|
10235
10466
|
assertExactOnce(units, artifacts);
|
|
10236
10467
|
const sources = units.map((unit, index) => {
|
|
10237
10468
|
const config = configs.get(unit.config_id);
|
|
10238
|
-
|
|
10469
|
+
const output = config.outputs.find((entry) => entry.agent === input.context.provider);
|
|
10470
|
+
const content = output ? applyTransform(config, output, { configs: [config] }) : config.content;
|
|
10471
|
+
return sourceForUnit({ ...config, content }, unit, index);
|
|
10239
10472
|
});
|
|
10240
10473
|
const planWithoutHash = {
|
|
10241
10474
|
schema: INSTRUCTION_GRAPH_PLAN_SCHEMA,
|
|
@@ -11819,7 +12052,7 @@ function formatCliError(err, env = process.env) {
|
|
|
11819
12052
|
var localStoreModulePromise = null;
|
|
11820
12053
|
function localStoreModule() {
|
|
11821
12054
|
if (!localStoreModulePromise)
|
|
11822
|
-
localStoreModulePromise = import("./local-
|
|
12055
|
+
localStoreModulePromise = import("./local-yxsbs8x3.js");
|
|
11823
12056
|
return localStoreModulePromise;
|
|
11824
12057
|
}
|
|
11825
12058
|
|
|
@@ -12100,7 +12333,9 @@ class CloudConfigStore {
|
|
|
12100
12333
|
return data.config;
|
|
12101
12334
|
}
|
|
12102
12335
|
async updateConfig(idOrSlug, input) {
|
|
12103
|
-
|
|
12336
|
+
validateExpectedConfigVersion(input.expected_version);
|
|
12337
|
+
const conditional = input.expected_version !== undefined;
|
|
12338
|
+
const { data } = await this.request(conditional ? "POST" : "PATCH", `/configs/${encodeURIComponent(idOrSlug)}${conditional ? "/conditional-update" : ""}`, input);
|
|
12104
12339
|
return data.config;
|
|
12105
12340
|
}
|
|
12106
12341
|
async deleteConfig(idOrSlug) {
|
|
@@ -12177,7 +12412,7 @@ class CloudConfigStore {
|
|
|
12177
12412
|
throw new ProfileNotFoundError(idOrSlug);
|
|
12178
12413
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
12179
12414
|
}
|
|
12180
|
-
async getProfileConfigBindings(idOrSlug) {
|
|
12415
|
+
async getProfileConfigBindings(idOrSlug, options = {}) {
|
|
12181
12416
|
let routeMissing = false;
|
|
12182
12417
|
const bindings = await aggregateBoundedCollection("profile config bindings", async (cursor) => {
|
|
12183
12418
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -12190,6 +12425,8 @@ class CloudConfigStore {
|
|
|
12190
12425
|
}, (binding) => `${binding.profile_id}\x00${binding.config_id}`);
|
|
12191
12426
|
if (!routeMissing)
|
|
12192
12427
|
return bindings;
|
|
12428
|
+
if (options.requireExplicit)
|
|
12429
|
+
throw new Error("HOSTED_BINDINGS_REQUIRED: profile config binding route is unavailable; refusing legacy activation fallback.");
|
|
12193
12430
|
const profile = await this.getProfile(idOrSlug);
|
|
12194
12431
|
const configs = await this.getProfileConfigs(idOrSlug);
|
|
12195
12432
|
return configs.map((config, sort_order) => ({
|
|
@@ -12254,7 +12491,7 @@ class CloudConfigStore {
|
|
|
12254
12491
|
async removeConfigFromProfile(profileIdOrSlug, configId) {
|
|
12255
12492
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
12256
12493
|
}
|
|
12257
|
-
async getProfileAssetBindings(profileIdOrSlug) {
|
|
12494
|
+
async getProfileAssetBindings(profileIdOrSlug, options = {}) {
|
|
12258
12495
|
let routeMissing = false;
|
|
12259
12496
|
const assets = await aggregateBoundedCollection("profile asset bindings", async (cursor) => {
|
|
12260
12497
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -12267,6 +12504,8 @@ class CloudConfigStore {
|
|
|
12267
12504
|
}, (asset) => `${asset.profile_id}\x00${asset.binding.assetKey}`);
|
|
12268
12505
|
if (!routeMissing)
|
|
12269
12506
|
return assets;
|
|
12507
|
+
if (options.requireExplicit)
|
|
12508
|
+
throw new Error("HOSTED_ASSETS_REQUIRED: profile asset binding route is unavailable; refusing an empty asset fallback.");
|
|
12270
12509
|
await this.getProfile(profileIdOrSlug);
|
|
12271
12510
|
return [];
|
|
12272
12511
|
}
|
|
@@ -12580,9 +12819,13 @@ async function ensureGlobalAgentRulesStandardConfig(store = resolveConfigStore()
|
|
|
12580
12819
|
let existing;
|
|
12581
12820
|
try {
|
|
12582
12821
|
existing = await store.getConfig(GLOBAL_AGENT_RULES_STANDARD_SLUG);
|
|
12583
|
-
} catch {
|
|
12822
|
+
} catch (error) {
|
|
12823
|
+
if (!(error instanceof ConfigNotFoundError))
|
|
12824
|
+
throw error;
|
|
12584
12825
|
return await store.createConfig(standardConfigInput(resolveAgentOperatingRulesPayload(null)));
|
|
12585
12826
|
}
|
|
12827
|
+
if (isRetiredInstructionSource(existing))
|
|
12828
|
+
return existing;
|
|
12586
12829
|
const payload = resolveAgentOperatingRulesPayload(existing.content);
|
|
12587
12830
|
const input = standardConfigInput(payload);
|
|
12588
12831
|
if (existing.content !== input.content || existing.description !== input.description || existing.category !== input.category || existing.agent !== input.agent || existing.format !== input.format || existing.kind !== input.kind || JSON.stringify(existing.tags) !== JSON.stringify(input.tags)) {
|
|
@@ -12621,7 +12864,7 @@ function detectMachineContext(overrides = {}) {
|
|
|
12621
12864
|
created_at: "",
|
|
12622
12865
|
os_family: osFamily,
|
|
12623
12866
|
home_dir: homeDir4,
|
|
12624
|
-
workspace_root: overrides.workspace_root ??
|
|
12867
|
+
workspace_root: overrides.workspace_root ?? "",
|
|
12625
12868
|
bun_bin_dir: bunBinDir,
|
|
12626
12869
|
bun_path: overrides.bun_path ?? defaultBunPath,
|
|
12627
12870
|
path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join7("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
|
|
@@ -12634,7 +12877,7 @@ function machineContextToVariables(machine) {
|
|
|
12634
12877
|
OS_FAMILY: machine.os_family,
|
|
12635
12878
|
ARCH: machine.arch ?? "",
|
|
12636
12879
|
HOME_DIR: machine.home_dir,
|
|
12637
|
-
WORKSPACE_ROOT: machine.workspace_root,
|
|
12880
|
+
...machine.workspace_root ? { WORKSPACE_ROOT: machine.workspace_root } : {},
|
|
12638
12881
|
BUN_BIN_DIR: machine.bun_bin_dir,
|
|
12639
12882
|
BUN_PATH: machine.bun_path,
|
|
12640
12883
|
PATH_PREFIX: machine.path_prefix
|
|
@@ -12688,4 +12931,4 @@ function renderMachineAwareContentPreview(content, variables) {
|
|
|
12688
12931
|
return isTemplate(content) ? renderTemplatePreview(content, variables) : { content, unresolved: [] };
|
|
12689
12932
|
}
|
|
12690
12933
|
|
|
12691
|
-
export { DEFAULT_LIST_LIMIT, parseLimit, paginate, truncateText, truncateMiddle, normalizeBoundedReadOptions, boundedReadPage, ensureGlobalAgentRulesStandardConfig, ensureCodewithSharedTodosStorageStandardConfig, redactFormatForTarget, redactContent, scanSecrets, isSecretVarName, SESSION_RENDER_MANAGED_MARKER, SESSION_RENDER_SCHEMA, SESSION_RENDER_MANIFEST_RELATIVE_PATH, SESSION_INSTRUCTION_LAYERS, getSessionRenderSnapshotDir, sessionRenderSnapshotWorkspaceRoot, PROJECT_CONTEXT_MAX_INPUT_BYTES, SESSION_MANAGED_INPUT_MAX_BYTES, ProjectContextError, parseProjectContextBundle, planProjectContext, observeProjectContextSessionGuard, withProjectContextSessionGuard, applyProjectContext, writeProjectContextCoordinatedFile, removeProjectContextCoordinatedFile, isRetiredOrUnsupportedConfigAgent, retiredOrUnsupportedAgentReason, applyTransform, normalizeProfileAssetBinding, observeCursorGlobalAuthorityAtPath, isCursorGlobalAuthorityPath, stampCursorGlobalAuthorityMarker, detectCursorAuthorityConflicts, detectClaudeAuthorityConflicts, ANTIGRAVITY_RULE_FILE_CHAR_LIMIT, SESSION_RENDERER_OWNER_ID, SESSION_RENDER_TOOLS, SESSION_RENDER_OWNED_CONFIG_TARGETS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, normalizeSessionInstructionSourceId, resolveSessionPath, planSessionRender, sourceFromFilePath, sourceFromConfig, sourcesFromIdentityExport, legacyProfileConfigBinding, normalizeProfileConfigBinding, planProfileSessionRender, normalizeOsFamily, detectMachineContext, machineContextToVariables, resolveProfileVariables, templateizeMachineContent, renderMachineAwareContentPreview, formatCliError, CloudConfigStore, resolveConfigStore };
|
|
12934
|
+
export { DEFAULT_LIST_LIMIT, parseLimit, paginate, truncateText, truncateMiddle, normalizeBoundedReadOptions, boundedReadPage, isRetiredInstructionSource, instructionSourceRejection, assertInstructionSource, ensureGlobalAgentRulesStandardConfig, ensureCodewithSharedTodosStorageStandardConfig, exports_external, redactFormatForTarget, redactContent, scanSecrets, isSecretVarName, CODEWITH_NATIVE_IMPORTS_ENV, SESSION_RENDER_MANAGED_MARKER, SESSION_RENDER_SCHEMA, SESSION_RENDER_MANIFEST_RELATIVE_PATH, SESSION_INSTRUCTION_LAYERS, getSessionRenderSnapshotDir, sessionRenderSnapshotWorkspaceRoot, PROJECT_CONTEXT_MAX_INPUT_BYTES, SESSION_MANAGED_INPUT_MAX_BYTES, ProjectContextError, parseProjectContextBundle, planProjectContext, observeProjectContextSessionGuard, withProjectContextSessionGuard, applyProjectContext, writeProjectContextCoordinatedFile, removeProjectContextCoordinatedFile, isRetiredOrUnsupportedConfigAgent, retiredOrUnsupportedAgentReason, applyTransform, normalizeProfileAssetBinding, observeCursorGlobalAuthorityAtPath, isCursorGlobalAuthorityPath, stampCursorGlobalAuthorityMarker, detectCursorAuthorityConflicts, detectClaudeAuthorityConflicts, ANTIGRAVITY_RULE_FILE_CHAR_LIMIT, SESSION_RENDERER_OWNER_ID, SESSION_RENDER_TOOLS, SESSION_RENDER_OWNED_CONFIG_TARGETS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, normalizeSessionInstructionSourceId, resolveSessionPath, planSessionRender, sourceFromFilePath, sourceFromConfig, sourcesFromIdentityExport, legacyProfileConfigBinding, normalizeProfileConfigBinding, planProfileSessionRender, normalizeOsFamily, detectMachineContext, machineContextToVariables, resolveProfileVariables, templateizeMachineContent, renderMachineAwareContentPreview, formatCliError, CloudConfigStore, resolveConfigStore };
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveConfigStore,
|
|
16
16
|
resolveProfileVariables,
|
|
17
17
|
stampCursorGlobalAuthorityMarker
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-dwagz53p.js";
|
|
19
19
|
import {
|
|
20
20
|
isSecretVarName,
|
|
21
21
|
redactFormatForTarget,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import {
|
|
25
25
|
ConfigApplyError,
|
|
26
26
|
parseTemplateVars
|
|
27
|
-
} from "./index-
|
|
27
|
+
} from "./index-27az1qb1.js";
|
|
28
28
|
|
|
29
29
|
// src/lib/apply.ts
|
|
30
30
|
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "fs";
|