@hasna/instructions 0.7.1 → 0.7.2
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 +34 -7
- package/dist/chunks/{apply-c3sd4agz.js → apply-ps6jjt6k.js} +3 -3
- package/dist/chunks/{apply-pnn7a3y7.js → apply-wj7wh5km.js} +3 -3
- package/dist/chunks/{index-pdpg8a44.js → index-18j7x3xw.js} +2 -2
- package/dist/chunks/{index-3djthcm6.js → index-27az1qb1.js} +28 -1
- package/dist/chunks/{index-ypcef3a2.js → index-ape24zc0.js} +2 -2
- package/dist/chunks/{index-jg8ptcwh.js → index-ek15201v.js} +2 -2
- package/dist/chunks/{index-6jncnnw7.js → index-n6nh6f5r.js} +119 -17
- package/dist/chunks/{index-aj66f6xr.js → index-pq18fdbj.js} +29 -6
- package/dist/chunks/{index-n3fjspr0.js → index-preyvj8n.js} +28 -1
- package/dist/chunks/{index-r7nfef2g.js → index-y8410ve0.js} +3 -3
- package/dist/chunks/{local-0a9gja58.js → local-1c1qxzvx.js} +15 -4
- package/dist/chunks/{local-969ye538.js → local-hc67bynj.js} +15 -4
- package/dist/chunks/{sync-q5hvwq6e.js → sync-12m3vs6g.js} +4 -4
- package/dist/chunks/{sync-xtkbm5br.js → sync-azd9t4p8.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 +596 -133
- 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 +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +658 -98
- 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/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/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 +24 -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 +34 -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.js +19 -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 +20 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +122 -8
- package/dist/server/openapi.d.ts +123 -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 +16 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,6 +83,24 @@ envelope. Its top-level fields are `configs`, `profiles`, `drift`, `secrets`,
|
|
|
83
83
|
`secrets.policy` is `redacted_on_ingest`. Run `instructions report` without
|
|
84
84
|
`--json` for the human-readable report.
|
|
85
85
|
|
|
86
|
+
### Conditional config updates
|
|
87
|
+
|
|
88
|
+
Read the current config version before preparing an edit, then pass that
|
|
89
|
+
`expected_version` to `updateConfig` (store/public SDK), `update_config` (MCP), or:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
instructions add ./rule.md --kind reference --name example-rule --update --expected-version 7
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Guarded clients use `POST /v1/configs/:id/conditional-update`, which requires
|
|
96
|
+
`expected_version`. The generated SDK also exposes `conditionalUpdateConfig` for
|
|
97
|
+
this operation. An older server returns 404 without mutation; clients never fall
|
|
98
|
+
back to an unconditional update. A version mismatch returns HTTP 409 with code
|
|
99
|
+
`CONFIG_VERSION_CONFLICT`, changing neither the config nor its snapshots. Refresh
|
|
100
|
+
and review the newer version before trying again. Calls without a precondition
|
|
101
|
+
retain their existing behavior. New servers also accept `expected_version` on
|
|
102
|
+
PATCH/PUT; use the dedicated conditional route when server capabilities are unknown.
|
|
103
|
+
|
|
86
104
|
## Package-Manager Secret Guard
|
|
87
105
|
|
|
88
106
|
`instructions package-manager-scan` blocks package-manager credential ingress without
|
|
@@ -361,13 +379,20 @@ upgrade.
|
|
|
361
379
|
|
|
362
380
|
`instructions session plan` and `instructions session apply` render
|
|
363
381
|
OpenIdentities and instruction sources into provider-native files for Claude,
|
|
364
|
-
Codex, Cursor, OpenCode, Codewith, Qwen, aicopilot, and Google Antigravity.
|
|
382
|
+
Codex, Cursor, OpenCode, Sumi, Codewith, Qwen, aicopilot, and Google Antigravity.
|
|
365
383
|
The old Google agent target is removed; Antigravity is the only Google coding
|
|
366
384
|
agent render target. Antigravity workspace rules are rendered to
|
|
367
385
|
`.agents/rules/*.md`; its current global rules and MCP files use Google's
|
|
368
386
|
legacy-named `~/.gemini/GEMINI.md` and `~/.gemini/config/mcp_config.json`
|
|
369
387
|
paths but remain owned by the `antigravity` target.
|
|
370
388
|
|
|
389
|
+
Sumi renders one flattened `AGENTS.md`. Pass its actual config directory from
|
|
390
|
+
`sumi debug paths config` as `--target-home`, or use `--project-root` for
|
|
391
|
+
repository instructions. Global plans return `SUMI_CONFIG_DIR`; project plans
|
|
392
|
+
do not change the global config environment. No OpenCode config or fragment
|
|
393
|
+
imports are written. See [session rendering](docs/session-rendering.md) for
|
|
394
|
+
capability limits and examples.
|
|
395
|
+
|
|
371
396
|
Qwen Code session rendering writes `QWEN.md` instructional context with
|
|
372
397
|
`QWEN_HOME` pointing at the rendered profile home. Known config sync also
|
|
373
398
|
tracks Qwen Code `QWEN.md` and `settings.json` files at `~/.qwen/...` and
|
|
@@ -536,14 +561,16 @@ and prior on-box-only evidence must be explicitly reconciled before use.
|
|
|
536
561
|
|
|
537
562
|
## Machine-aware Profiles
|
|
538
563
|
|
|
539
|
-
`instructions init` seeds two platform profiles:
|
|
564
|
+
`instructions init` seeds two empty platform profiles:
|
|
540
565
|
|
|
541
|
-
- `linux-arm64` for
|
|
542
|
-
- `macos-arm64` for
|
|
566
|
+
- `linux-arm64` for Linux arm64
|
|
567
|
+
- `macos-arm64` for macOS arm64
|
|
543
568
|
|
|
544
|
-
|
|
545
|
-
`{{BUN_BIN_DIR}}`, `{{BUN_PATH}}`, and
|
|
546
|
-
|
|
569
|
+
The public presets contain no fleet hostnames or workspace paths. They resolve
|
|
570
|
+
portable tool variables such as `{{BUN_BIN_DIR}}`, `{{BUN_PATH}}`, and
|
|
571
|
+
`{{PATH_PREFIX}}`. Instruction membership is never bulk-copied from the config
|
|
572
|
+
registry; bind reviewed provider/project/role sources explicitly before compiling
|
|
573
|
+
a prompt profile.
|
|
547
574
|
|
|
548
575
|
They also include the project channel variable used by agent-managed project
|
|
549
576
|
workflows:
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
getConfigHome,
|
|
9
9
|
normalizeTargetPath,
|
|
10
10
|
previewConfigs
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
11
|
+
} from "./index-ape24zc0.js";
|
|
12
|
+
import"./index-pq18fdbj.js";
|
|
13
13
|
import"./index-35z65jsa.js";
|
|
14
|
-
import"./index-
|
|
14
|
+
import"./index-27az1qb1.js";
|
|
15
15
|
import"./index-nnwp92tk.js";
|
|
16
16
|
export {
|
|
17
17
|
previewConfigs,
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
getConfigHome,
|
|
9
9
|
normalizeTargetPath,
|
|
10
10
|
previewConfigs
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-
|
|
11
|
+
} from "./index-y8410ve0.js";
|
|
12
|
+
import"./index-n6nh6f5r.js";
|
|
13
|
+
import"./index-preyvj8n.js";
|
|
14
14
|
import"./index-fpeyzn3n.js";
|
|
15
15
|
import"./index-bsan4c16.js";
|
|
16
16
|
export {
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
expandPath,
|
|
6
6
|
getConfigHome,
|
|
7
7
|
normalizeTargetPath
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-y8410ve0.js";
|
|
9
9
|
import {
|
|
10
10
|
applyTransform,
|
|
11
11
|
detectMachineContext,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolveConfigStore,
|
|
17
17
|
retiredOrUnsupportedAgentReason,
|
|
18
18
|
templateizeMachineContent
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-n6nh6f5r.js";
|
|
20
20
|
|
|
21
21
|
// src/lib/sync.ts
|
|
22
22
|
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -4,6 +4,7 @@ var CONFIG_AGENTS = [
|
|
|
4
4
|
"claude",
|
|
5
5
|
"codex",
|
|
6
6
|
"opencode",
|
|
7
|
+
"sumi",
|
|
7
8
|
"cursor",
|
|
8
9
|
"codewith",
|
|
9
10
|
"aicopilot",
|
|
@@ -28,6 +29,32 @@ var ASSET_DESTINATION_STRATEGIES = ["emit-file", "install-local", "install-marke
|
|
|
28
29
|
var ASSET_SCOPES = ["global", "project", "session"];
|
|
29
30
|
var ASSET_UNINSTALL_POLICIES = ["remove-managed", "retain"];
|
|
30
31
|
var ASSET_ROLLBACK_POLICIES = ["snapshot", "installer-receipt", "none"];
|
|
32
|
+
class InvalidExpectedVersionError extends Error {
|
|
33
|
+
code = "INVALID_EXPECTED_VERSION";
|
|
34
|
+
constructor() {
|
|
35
|
+
super("expected_version must be a positive safe integer");
|
|
36
|
+
this.name = "InvalidExpectedVersionError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function validateExpectedConfigVersion(value) {
|
|
40
|
+
if (value !== undefined && (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1)) {
|
|
41
|
+
throw new InvalidExpectedVersionError;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class ConfigVersionConflictError extends Error {
|
|
46
|
+
config_id;
|
|
47
|
+
expected_version;
|
|
48
|
+
code = "CONFIG_VERSION_CONFLICT";
|
|
49
|
+
status = 409;
|
|
50
|
+
constructor(config_id, expected_version) {
|
|
51
|
+
super(`Config version conflict: ${config_id} no longer has expected version ${expected_version}`);
|
|
52
|
+
this.config_id = config_id;
|
|
53
|
+
this.expected_version = expected_version;
|
|
54
|
+
this.name = "ConfigVersionConflictError";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
31
58
|
class ConfigNotFoundError extends Error {
|
|
32
59
|
constructor(id) {
|
|
33
60
|
super(`Config not found: ${id}`);
|
|
@@ -114,4 +141,4 @@ function isTemplate(content) {
|
|
|
114
141
|
return VAR_PATTERN.test(content);
|
|
115
142
|
}
|
|
116
143
|
|
|
117
|
-
export { CONFIG_AGENTS, PROFILE_CONFIG_BINDING_SCHEMA, INSTRUCTION_ACTIVATION_MODES, INSTRUCTION_FALLBACKS, PROFILE_ASSET_BINDING_SCHEMA, ASSET_KINDS, ASSET_DESTINATION_STRATEGIES, ASSET_SCOPES, ASSET_UNINSTALL_POLICIES, ASSET_ROLLBACK_POLICIES, ConfigNotFoundError, ProfileNotFoundError, ConfigApplyError, parseTemplateVars, extractTemplateVars, renderTemplate, renderTemplatePreview, isTemplate };
|
|
144
|
+
export { CONFIG_AGENTS, PROFILE_CONFIG_BINDING_SCHEMA, INSTRUCTION_ACTIVATION_MODES, INSTRUCTION_FALLBACKS, PROFILE_ASSET_BINDING_SCHEMA, ASSET_KINDS, ASSET_DESTINATION_STRATEGIES, ASSET_SCOPES, ASSET_UNINSTALL_POLICIES, ASSET_ROLLBACK_POLICIES, validateExpectedConfigVersion, ConfigVersionConflictError, ConfigNotFoundError, ProfileNotFoundError, ConfigApplyError, parseTemplateVars, extractTemplateVars, renderTemplate, renderTemplatePreview, isTemplate };
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveConfigStore,
|
|
16
16
|
resolveProfileVariables,
|
|
17
17
|
stampCursorGlobalAuthorityMarker
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-pq18fdbj.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";
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
expandPath,
|
|
6
6
|
getConfigHome,
|
|
7
7
|
normalizeTargetPath
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-ape24zc0.js";
|
|
9
9
|
import {
|
|
10
10
|
applyTransform,
|
|
11
11
|
detectMachineContext,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
resolveConfigStore,
|
|
14
14
|
retiredOrUnsupportedAgentReason,
|
|
15
15
|
templateizeMachineContent
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-pq18fdbj.js";
|
|
17
17
|
import {
|
|
18
18
|
isSecretVarName,
|
|
19
19
|
redactContent,
|
|
@@ -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":
|
|
@@ -7515,6 +7552,7 @@ var DEFAULT_ASSET_SURFACES = Object.freeze({
|
|
|
7515
7552
|
codex: "cli",
|
|
7516
7553
|
cursor: "ide",
|
|
7517
7554
|
opencode: "cli",
|
|
7555
|
+
sumi: "cli",
|
|
7518
7556
|
codewith: "cli",
|
|
7519
7557
|
qwen: "cli",
|
|
7520
7558
|
aicopilot: "cli",
|
|
@@ -8178,6 +8216,7 @@ var SESSION_RENDER_TOOLS = [
|
|
|
8178
8216
|
"codex",
|
|
8179
8217
|
"cursor",
|
|
8180
8218
|
"opencode",
|
|
8219
|
+
"sumi",
|
|
8181
8220
|
"codewith",
|
|
8182
8221
|
"qwen",
|
|
8183
8222
|
"aicopilot",
|
|
@@ -8266,6 +8305,15 @@ var SESSION_TOOL_ADAPTERS = {
|
|
|
8266
8305
|
description: "OpenCode AGENTS.md plus opencode.json instructions pointing at managed fragments.",
|
|
8267
8306
|
providerSurface: "legacy-dual"
|
|
8268
8307
|
},
|
|
8308
|
+
sumi: {
|
|
8309
|
+
tool: "sumi",
|
|
8310
|
+
mode: "flattened-markdown",
|
|
8311
|
+
indexFile: "AGENTS.md",
|
|
8312
|
+
managedDir: SESSION_RENDER_INSTRUCTIONS_MANAGED_DIR,
|
|
8313
|
+
envVar: "SUMI_CONFIG_DIR",
|
|
8314
|
+
nativeImports: false,
|
|
8315
|
+
description: "Sumi native AGENTS.md in the explicit resolved config directory or project root."
|
|
8316
|
+
},
|
|
8269
8317
|
aicopilot: {
|
|
8270
8318
|
tool: "aicopilot",
|
|
8271
8319
|
mode: "flattened-markdown",
|
|
@@ -8550,9 +8598,19 @@ function skippedSource(source, reason) {
|
|
|
8550
8598
|
};
|
|
8551
8599
|
}
|
|
8552
8600
|
function normalizeSources(sources, tool, allowEmptySources) {
|
|
8553
|
-
const
|
|
8601
|
+
const providerSkipped = [];
|
|
8602
|
+
const normalized = sources.flatMap((source, index) => {
|
|
8554
8603
|
if (!source.id.trim())
|
|
8555
8604
|
throw new Error("Session instruction source id is required.");
|
|
8605
|
+
if (source.targetProviders?.length && !providerTargetsTool(source.targetProviders, tool)) {
|
|
8606
|
+
providerSkipped.push({
|
|
8607
|
+
id: source.id,
|
|
8608
|
+
label: source.label ?? source.id,
|
|
8609
|
+
targetProviders: source.targetProviders,
|
|
8610
|
+
reason: "instruction source targets a different provider"
|
|
8611
|
+
});
|
|
8612
|
+
return [];
|
|
8613
|
+
}
|
|
8556
8614
|
const floored = applyAgentOperatingRulesFloor(source, source.content ?? "");
|
|
8557
8615
|
const content = filterProviderOnlyBlocks(floored.content, tool);
|
|
8558
8616
|
const normalized2 = {
|
|
@@ -8571,7 +8629,7 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
8571
8629
|
if (!allowEmptySources && !normalized2.content.trim() && normalized2.resolvedRules.length === 0 && !hasPathReferences) {
|
|
8572
8630
|
throw new Error(`Session instruction source "${source.id}" is empty. Pass --allow-empty-sources only for explicit empty renders.`);
|
|
8573
8631
|
}
|
|
8574
|
-
return normalized2;
|
|
8632
|
+
return [normalized2];
|
|
8575
8633
|
});
|
|
8576
8634
|
const originalOrder = [...normalized].sort(compareSessionInstructionSources);
|
|
8577
8635
|
const deduplicated = deduplicateSemanticPolicySources(normalized);
|
|
@@ -8579,7 +8637,7 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
8579
8637
|
validateTargetedReplacementSources(originalOrder, ordered, deduplicated.skipped, tool);
|
|
8580
8638
|
rejectDuplicateSourceSlugs(ordered);
|
|
8581
8639
|
rejectDuplicateRulePaths(ordered);
|
|
8582
|
-
return { sources: ordered, skipped: deduplicated.skipped };
|
|
8640
|
+
return { sources: ordered, skipped: [...providerSkipped, ...deduplicated.skipped] };
|
|
8583
8641
|
}
|
|
8584
8642
|
function compareSessionInstructionSources(a, b) {
|
|
8585
8643
|
return SESSION_LAYER_RANK[a.resolvedLayer] - SESSION_LAYER_RANK[b.resolvedLayer] || a.resolvedOrder - b.resolvedOrder || a.id.localeCompare(b.id);
|
|
@@ -9185,6 +9243,11 @@ function isNativeProfileSessionTarget(input) {
|
|
|
9185
9243
|
return (input.tool === "grok" || input.tool === "devin") && Boolean(input.targetHome?.trim()) && !input.projectRoot;
|
|
9186
9244
|
}
|
|
9187
9245
|
function adapterFor(input) {
|
|
9246
|
+
if (input.tool === "sumi" && input.projectRoot) {
|
|
9247
|
+
if (input.providerSurface)
|
|
9248
|
+
throw new Error(`Provider surface ${input.providerSurface} is not valid for Sumi.`);
|
|
9249
|
+
return Object.freeze({ ...SESSION_TOOL_ADAPTERS.sumi, projectScoped: true, envVar: undefined });
|
|
9250
|
+
}
|
|
9188
9251
|
if (input.tool === "opencode" && input.providerSurface) {
|
|
9189
9252
|
if (input.providerSurface !== "opencode-config-instructions" && input.providerSurface !== "opencode-agents-md") {
|
|
9190
9253
|
throw new Error(`Provider surface ${input.providerSurface} is not valid for OpenCode.`);
|
|
@@ -9226,7 +9289,7 @@ function adapterFor(input) {
|
|
|
9226
9289
|
}
|
|
9227
9290
|
if (input.tool !== "codewith")
|
|
9228
9291
|
return SESSION_TOOL_ADAPTERS[input.tool];
|
|
9229
|
-
const gatedNativeImports = input.codewithNativeImports
|
|
9292
|
+
const gatedNativeImports = input.codewithNativeImports ?? (process.env[CODEWITH_NATIVE_IMPORTS_ENV] === "1" || process.env[CODEWITH_NATIVE_IMPORTS_ENV] === "true");
|
|
9230
9293
|
return gatedNativeImports ? CODEWITH_NATIVE_ADAPTER : CODEWITH_FLATTENED_ADAPTER;
|
|
9231
9294
|
}
|
|
9232
9295
|
function getHomeDir() {
|
|
@@ -9277,6 +9340,13 @@ function assertSafeTargetRoot(targetHome) {
|
|
|
9277
9340
|
return normalized;
|
|
9278
9341
|
}
|
|
9279
9342
|
function resolveRenderTarget(input, adapter) {
|
|
9343
|
+
if (input.tool === "sumi" && !input.projectRoot && !input.targetHome?.trim()) {
|
|
9344
|
+
return {
|
|
9345
|
+
targetHome: defaultTargetHome(input.tool, input.profile, input.sessionId),
|
|
9346
|
+
targetKind: "blocked",
|
|
9347
|
+
blockers: ["Sumi requires --target-home from `sumi debug paths config`, or --project-root for repository AGENTS.md."]
|
|
9348
|
+
};
|
|
9349
|
+
}
|
|
9280
9350
|
if (adapter.projectScoped) {
|
|
9281
9351
|
if (!input.projectRoot) {
|
|
9282
9352
|
const label = input.tool === "cursor" ? "Cursor rules" : input.tool === "antigravity" ? "Antigravity rules" : `${adapter.description.split(".")[0]} files`;
|
|
@@ -9378,6 +9448,14 @@ function planSessionRender(input) {
|
|
|
9378
9448
|
const normalized = normalizeSources(input.sources, input.tool, allowEmptySources);
|
|
9379
9449
|
const composed = composeSources(normalized.sources, input.tool);
|
|
9380
9450
|
const orderedSources = composed.sources;
|
|
9451
|
+
if (input.tool === "sumi") {
|
|
9452
|
+
for (const source of orderedSources) {
|
|
9453
|
+
const activation = source.metadata?.["activation"];
|
|
9454
|
+
if (source.globs?.length || source.resolvedRules.some((rule) => rule.globs?.length) || activation?.mode && activation.mode !== "always") {
|
|
9455
|
+
throw new Error(`Sumi AGENTS.md cannot preserve conditional activation for source ${source.id}; compile a profile with an explicit supported fallback.`);
|
|
9456
|
+
}
|
|
9457
|
+
}
|
|
9458
|
+
}
|
|
9381
9459
|
const skippedSources = [
|
|
9382
9460
|
...input.skippedSources ?? [],
|
|
9383
9461
|
...normalized.skipped,
|
|
@@ -9421,6 +9499,7 @@ function planSessionRender(input) {
|
|
|
9421
9499
|
adapterMode: adapter.mode,
|
|
9422
9500
|
profile: input.profile,
|
|
9423
9501
|
sessionId: input.sessionId ?? null,
|
|
9502
|
+
...input.refreshSelector ? { refreshSelector: input.refreshSelector } : {},
|
|
9424
9503
|
targetHome,
|
|
9425
9504
|
targetKind,
|
|
9426
9505
|
targetOwner,
|
|
@@ -9933,6 +10012,7 @@ var DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
|
|
|
9933
10012
|
codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
|
|
9934
10013
|
cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
|
|
9935
10014
|
opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
|
|
10015
|
+
sumi: capability("sumi", ">=0.2.22 <0.3.0", "flattened", "AGENTS.md"),
|
|
9936
10016
|
codewith: capability("codewith", ">=0.1.0", "flattened", "CODEWITH.md"),
|
|
9937
10017
|
qwen: capability("qwen", ">=0.1.0", "flattened", "QWEN.md"),
|
|
9938
10018
|
aicopilot: capability("aicopilot", ">=0.1.0", "flattened", "AICOPILOT.md"),
|
|
@@ -10155,12 +10235,22 @@ function compileInstructionGraph(input) {
|
|
|
10155
10235
|
const selector = binding.providers?.find((entry) => entry.provider === input.context.provider || entry.provider === "global");
|
|
10156
10236
|
if (binding.providers?.length && !selector)
|
|
10157
10237
|
continue;
|
|
10238
|
+
const output = config.outputs.find((entry) => entry.agent === input.context.provider);
|
|
10239
|
+
if (!binding.providers?.length && config.agent !== "global" && config.agent !== input.context.provider && !output) {
|
|
10240
|
+
diagnostics.push({ severity: "info", code: "SOURCE_PROVIDER_NOT_SELECTED", config_id: configId, message: `${config.slug} targets ${config.agent}, not ${input.context.provider}.` });
|
|
10241
|
+
continue;
|
|
10242
|
+
}
|
|
10158
10243
|
if (selector?.version_range && !providerVersionSatisfies(input.context.provider_version, selector.version_range)) {
|
|
10159
10244
|
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
10245
|
continue;
|
|
10161
10246
|
}
|
|
10162
10247
|
if (!activationMatches(binding.activation, config, input.context))
|
|
10163
10248
|
continue;
|
|
10249
|
+
const rejection = instructionSourceRejection(config);
|
|
10250
|
+
if (rejection) {
|
|
10251
|
+
diagnostics.push({ severity: !binding.required && binding.fallback === "omit" ? "warning" : "error", code: "SOURCE_NOT_INSTRUCTION", config_id: configId, message: `${config.slug}: ${rejection}.` });
|
|
10252
|
+
continue;
|
|
10253
|
+
}
|
|
10164
10254
|
if (capability2.activation_modes.includes(binding.activation.mode)) {
|
|
10165
10255
|
selected.add(configId);
|
|
10166
10256
|
effective.set(configId, binding.activation);
|
|
@@ -10235,7 +10325,9 @@ function compileInstructionGraph(input) {
|
|
|
10235
10325
|
assertExactOnce(units, artifacts);
|
|
10236
10326
|
const sources = units.map((unit, index) => {
|
|
10237
10327
|
const config = configs.get(unit.config_id);
|
|
10238
|
-
|
|
10328
|
+
const output = config.outputs.find((entry) => entry.agent === input.context.provider);
|
|
10329
|
+
const content = output ? applyTransform(config, output, { configs: [config] }) : config.content;
|
|
10330
|
+
return sourceForUnit({ ...config, content }, unit, index);
|
|
10239
10331
|
});
|
|
10240
10332
|
const planWithoutHash = {
|
|
10241
10333
|
schema: INSTRUCTION_GRAPH_PLAN_SCHEMA,
|
|
@@ -11819,7 +11911,7 @@ function formatCliError(err, env = process.env) {
|
|
|
11819
11911
|
var localStoreModulePromise = null;
|
|
11820
11912
|
function localStoreModule() {
|
|
11821
11913
|
if (!localStoreModulePromise)
|
|
11822
|
-
localStoreModulePromise = import("./local-
|
|
11914
|
+
localStoreModulePromise = import("./local-hc67bynj.js");
|
|
11823
11915
|
return localStoreModulePromise;
|
|
11824
11916
|
}
|
|
11825
11917
|
|
|
@@ -12100,7 +12192,9 @@ class CloudConfigStore {
|
|
|
12100
12192
|
return data.config;
|
|
12101
12193
|
}
|
|
12102
12194
|
async updateConfig(idOrSlug, input) {
|
|
12103
|
-
|
|
12195
|
+
validateExpectedConfigVersion(input.expected_version);
|
|
12196
|
+
const conditional = input.expected_version !== undefined;
|
|
12197
|
+
const { data } = await this.request(conditional ? "POST" : "PATCH", `/configs/${encodeURIComponent(idOrSlug)}${conditional ? "/conditional-update" : ""}`, input);
|
|
12104
12198
|
return data.config;
|
|
12105
12199
|
}
|
|
12106
12200
|
async deleteConfig(idOrSlug) {
|
|
@@ -12177,7 +12271,7 @@ class CloudConfigStore {
|
|
|
12177
12271
|
throw new ProfileNotFoundError(idOrSlug);
|
|
12178
12272
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
12179
12273
|
}
|
|
12180
|
-
async getProfileConfigBindings(idOrSlug) {
|
|
12274
|
+
async getProfileConfigBindings(idOrSlug, options = {}) {
|
|
12181
12275
|
let routeMissing = false;
|
|
12182
12276
|
const bindings = await aggregateBoundedCollection("profile config bindings", async (cursor) => {
|
|
12183
12277
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -12190,6 +12284,8 @@ class CloudConfigStore {
|
|
|
12190
12284
|
}, (binding) => `${binding.profile_id}\x00${binding.config_id}`);
|
|
12191
12285
|
if (!routeMissing)
|
|
12192
12286
|
return bindings;
|
|
12287
|
+
if (options.requireExplicit)
|
|
12288
|
+
throw new Error("HOSTED_BINDINGS_REQUIRED: profile config binding route is unavailable; refusing legacy activation fallback.");
|
|
12193
12289
|
const profile = await this.getProfile(idOrSlug);
|
|
12194
12290
|
const configs = await this.getProfileConfigs(idOrSlug);
|
|
12195
12291
|
return configs.map((config, sort_order) => ({
|
|
@@ -12254,7 +12350,7 @@ class CloudConfigStore {
|
|
|
12254
12350
|
async removeConfigFromProfile(profileIdOrSlug, configId) {
|
|
12255
12351
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
12256
12352
|
}
|
|
12257
|
-
async getProfileAssetBindings(profileIdOrSlug) {
|
|
12353
|
+
async getProfileAssetBindings(profileIdOrSlug, options = {}) {
|
|
12258
12354
|
let routeMissing = false;
|
|
12259
12355
|
const assets = await aggregateBoundedCollection("profile asset bindings", async (cursor) => {
|
|
12260
12356
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -12267,6 +12363,8 @@ class CloudConfigStore {
|
|
|
12267
12363
|
}, (asset) => `${asset.profile_id}\x00${asset.binding.assetKey}`);
|
|
12268
12364
|
if (!routeMissing)
|
|
12269
12365
|
return assets;
|
|
12366
|
+
if (options.requireExplicit)
|
|
12367
|
+
throw new Error("HOSTED_ASSETS_REQUIRED: profile asset binding route is unavailable; refusing an empty asset fallback.");
|
|
12270
12368
|
await this.getProfile(profileIdOrSlug);
|
|
12271
12369
|
return [];
|
|
12272
12370
|
}
|
|
@@ -12580,9 +12678,13 @@ async function ensureGlobalAgentRulesStandardConfig(store = resolveConfigStore()
|
|
|
12580
12678
|
let existing;
|
|
12581
12679
|
try {
|
|
12582
12680
|
existing = await store.getConfig(GLOBAL_AGENT_RULES_STANDARD_SLUG);
|
|
12583
|
-
} catch {
|
|
12681
|
+
} catch (error) {
|
|
12682
|
+
if (!(error instanceof ConfigNotFoundError))
|
|
12683
|
+
throw error;
|
|
12584
12684
|
return await store.createConfig(standardConfigInput(resolveAgentOperatingRulesPayload(null)));
|
|
12585
12685
|
}
|
|
12686
|
+
if (isRetiredInstructionSource(existing))
|
|
12687
|
+
return existing;
|
|
12586
12688
|
const payload = resolveAgentOperatingRulesPayload(existing.content);
|
|
12587
12689
|
const input = standardConfigInput(payload);
|
|
12588
12690
|
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)) {
|
|
@@ -12688,4 +12790,4 @@ function renderMachineAwareContentPreview(content, variables) {
|
|
|
12688
12790
|
return isTemplate(content) ? renderTemplatePreview(content, variables) : { content, unresolved: [] };
|
|
12689
12791
|
}
|
|
12690
12792
|
|
|
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 };
|
|
12793
|
+
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 };
|
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
ProfileNotFoundError,
|
|
15
15
|
isTemplate,
|
|
16
16
|
renderTemplate,
|
|
17
|
-
renderTemplatePreview
|
|
18
|
-
|
|
17
|
+
renderTemplatePreview,
|
|
18
|
+
validateExpectedConfigVersion
|
|
19
|
+
} from "./index-27az1qb1.js";
|
|
19
20
|
import {
|
|
20
21
|
__export,
|
|
21
22
|
__require
|
|
@@ -114,6 +115,9 @@ function buildCodexAgentsMd(source, context = {}) {
|
|
|
114
115
|
function buildOpenCodeAgentsMd(source, context = {}) {
|
|
115
116
|
return flattenWithRules(source, context);
|
|
116
117
|
}
|
|
118
|
+
function buildSumiAgentsMd(source, context = {}) {
|
|
119
|
+
return flattenWithRules(source, context);
|
|
120
|
+
}
|
|
117
121
|
function buildCursorMdc(source) {
|
|
118
122
|
const stem = source.target_path ? basename(source.target_path, extname(source.target_path)) : source.slug;
|
|
119
123
|
const description = source.name || stem;
|
|
@@ -142,6 +146,8 @@ function applyTransform(source, output, context = {}) {
|
|
|
142
146
|
return buildCodexAgentsMd(source, context);
|
|
143
147
|
case "opencode-flat":
|
|
144
148
|
return buildOpenCodeAgentsMd(source, context);
|
|
149
|
+
case "sumi-flat":
|
|
150
|
+
return buildSumiAgentsMd(source, context);
|
|
145
151
|
case "cursor-mdc":
|
|
146
152
|
return buildCursorMdc(source);
|
|
147
153
|
case "skill-neutral":
|
|
@@ -409,6 +415,7 @@ var DEFAULT_ASSET_SURFACES = Object.freeze({
|
|
|
409
415
|
codex: "cli",
|
|
410
416
|
cursor: "ide",
|
|
411
417
|
opencode: "cli",
|
|
418
|
+
sumi: "cli",
|
|
412
419
|
codewith: "cli",
|
|
413
420
|
qwen: "cli",
|
|
414
421
|
aicopilot: "cli",
|
|
@@ -534,6 +541,7 @@ var DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
|
|
|
534
541
|
codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
|
|
535
542
|
cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
|
|
536
543
|
opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
|
|
544
|
+
sumi: capability("sumi", ">=0.2.22 <0.3.0", "flattened", "AGENTS.md"),
|
|
537
545
|
codewith: capability("codewith", ">=0.1.0", "flattened", "CODEWITH.md"),
|
|
538
546
|
qwen: capability("qwen", ">=0.1.0", "flattened", "QWEN.md"),
|
|
539
547
|
aicopilot: capability("aicopilot", ">=0.1.0", "flattened", "AICOPILOT.md"),
|
|
@@ -2115,7 +2123,7 @@ function isNotFoundHttpError2(err) {
|
|
|
2115
2123
|
var localStoreModulePromise = null;
|
|
2116
2124
|
function localStoreModule() {
|
|
2117
2125
|
if (!localStoreModulePromise)
|
|
2118
|
-
localStoreModulePromise = import("./local-
|
|
2126
|
+
localStoreModulePromise = import("./local-1c1qxzvx.js");
|
|
2119
2127
|
return localStoreModulePromise;
|
|
2120
2128
|
}
|
|
2121
2129
|
|
|
@@ -2396,7 +2404,9 @@ class CloudConfigStore {
|
|
|
2396
2404
|
return data.config;
|
|
2397
2405
|
}
|
|
2398
2406
|
async updateConfig(idOrSlug, input) {
|
|
2399
|
-
|
|
2407
|
+
validateExpectedConfigVersion(input.expected_version);
|
|
2408
|
+
const conditional = input.expected_version !== undefined;
|
|
2409
|
+
const { data } = await this.request(conditional ? "POST" : "PATCH", `/configs/${encodeURIComponent(idOrSlug)}${conditional ? "/conditional-update" : ""}`, input);
|
|
2400
2410
|
return data.config;
|
|
2401
2411
|
}
|
|
2402
2412
|
async deleteConfig(idOrSlug) {
|
|
@@ -2473,7 +2483,7 @@ class CloudConfigStore {
|
|
|
2473
2483
|
throw new ProfileNotFoundError(idOrSlug);
|
|
2474
2484
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
2475
2485
|
}
|
|
2476
|
-
async getProfileConfigBindings(idOrSlug) {
|
|
2486
|
+
async getProfileConfigBindings(idOrSlug, options = {}) {
|
|
2477
2487
|
let routeMissing = false;
|
|
2478
2488
|
const bindings = await aggregateBoundedCollection("profile config bindings", async (cursor) => {
|
|
2479
2489
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -2486,6 +2496,8 @@ class CloudConfigStore {
|
|
|
2486
2496
|
}, (binding) => `${binding.profile_id}\x00${binding.config_id}`);
|
|
2487
2497
|
if (!routeMissing)
|
|
2488
2498
|
return bindings;
|
|
2499
|
+
if (options.requireExplicit)
|
|
2500
|
+
throw new Error("HOSTED_BINDINGS_REQUIRED: profile config binding route is unavailable; refusing legacy activation fallback.");
|
|
2489
2501
|
const profile = await this.getProfile(idOrSlug);
|
|
2490
2502
|
const configs = await this.getProfileConfigs(idOrSlug);
|
|
2491
2503
|
return configs.map((config, sort_order) => ({
|
|
@@ -2550,7 +2562,7 @@ class CloudConfigStore {
|
|
|
2550
2562
|
async removeConfigFromProfile(profileIdOrSlug, configId) {
|
|
2551
2563
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
2552
2564
|
}
|
|
2553
|
-
async getProfileAssetBindings(profileIdOrSlug) {
|
|
2565
|
+
async getProfileAssetBindings(profileIdOrSlug, options = {}) {
|
|
2554
2566
|
let routeMissing = false;
|
|
2555
2567
|
const assets = await aggregateBoundedCollection("profile asset bindings", async (cursor) => {
|
|
2556
2568
|
const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
|
|
@@ -2563,6 +2575,8 @@ class CloudConfigStore {
|
|
|
2563
2575
|
}, (asset) => `${asset.profile_id}\x00${asset.binding.assetKey}`);
|
|
2564
2576
|
if (!routeMissing)
|
|
2565
2577
|
return assets;
|
|
2578
|
+
if (options.requireExplicit)
|
|
2579
|
+
throw new Error("HOSTED_ASSETS_REQUIRED: profile asset binding route is unavailable; refusing an empty asset fallback.");
|
|
2566
2580
|
await this.getProfile(profileIdOrSlug);
|
|
2567
2581
|
return [];
|
|
2568
2582
|
}
|
|
@@ -7199,6 +7213,15 @@ var SESSION_TOOL_ADAPTERS = {
|
|
|
7199
7213
|
description: "OpenCode AGENTS.md plus opencode.json instructions pointing at managed fragments.",
|
|
7200
7214
|
providerSurface: "legacy-dual"
|
|
7201
7215
|
},
|
|
7216
|
+
sumi: {
|
|
7217
|
+
tool: "sumi",
|
|
7218
|
+
mode: "flattened-markdown",
|
|
7219
|
+
indexFile: "AGENTS.md",
|
|
7220
|
+
managedDir: SESSION_RENDER_INSTRUCTIONS_MANAGED_DIR,
|
|
7221
|
+
envVar: "SUMI_CONFIG_DIR",
|
|
7222
|
+
nativeImports: false,
|
|
7223
|
+
description: "Sumi native AGENTS.md in the explicit resolved config directory or project root."
|
|
7224
|
+
},
|
|
7202
7225
|
aicopilot: {
|
|
7203
7226
|
tool: "aicopilot",
|
|
7204
7227
|
mode: "flattened-markdown",
|