@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.
Files changed (67) hide show
  1. package/README.md +47 -7
  2. package/dist/chunks/{apply-c3sd4agz.js → apply-1gyr8r0x.js} +3 -3
  3. package/dist/chunks/{apply-pnn7a3y7.js → apply-fyfzqc7s.js} +3 -3
  4. package/dist/chunks/{index-3djthcm6.js → index-27az1qb1.js} +28 -1
  5. package/dist/chunks/{index-r7nfef2g.js → index-6sbmg1vc.js} +3 -3
  6. package/dist/chunks/{index-pdpg8a44.js → index-axs3yftz.js} +2 -2
  7. package/dist/chunks/{index-aj66f6xr.js → index-dwagz53p.js} +92 -8
  8. package/dist/chunks/{index-6jncnnw7.js → index-enh4yv85.js} +274 -31
  9. package/dist/chunks/{index-ypcef3a2.js → index-n9arv47w.js} +2 -2
  10. package/dist/chunks/{index-n3fjspr0.js → index-preyvj8n.js} +28 -1
  11. package/dist/chunks/{index-jg8ptcwh.js → index-z27xp7fh.js} +2 -2
  12. package/dist/chunks/{local-0a9gja58.js → local-5dsm856v.js} +15 -4
  13. package/dist/chunks/{local-969ye538.js → local-yxsbs8x3.js} +15 -4
  14. package/dist/chunks/{sync-xtkbm5br.js → sync-6r1v8hd3.js} +4 -4
  15. package/dist/chunks/{sync-q5hvwq6e.js → sync-k3pab4s6.js} +4 -4
  16. package/dist/chunks/{template-wgnzdn7h.js → template-e4qrxs8p.js} +1 -1
  17. package/dist/chunks/{template-fsfxpe4p.js → template-nhn124zd.js} +1 -1
  18. package/dist/cli/index.js +1018 -584
  19. package/dist/data/config-store.d.ts +12 -4
  20. package/dist/data/config-store.d.ts.map +1 -1
  21. package/dist/db/configs.d.ts.map +1 -1
  22. package/dist/index.d.ts +8 -4
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1264 -601
  25. package/dist/lib/asset-plan.d.ts +4 -1
  26. package/dist/lib/asset-plan.d.ts.map +1 -1
  27. package/dist/lib/codewith-shared-todos-storage-standard.d.ts.map +1 -1
  28. package/dist/lib/dangerous-operation-guard-standard.d.ts.map +1 -1
  29. package/dist/lib/global-agent-rules-standard.d.ts.map +1 -1
  30. package/dist/lib/global-source-coverage.d.ts +12 -7
  31. package/dist/lib/global-source-coverage.d.ts.map +1 -1
  32. package/dist/lib/harness-discovery.d.ts +52 -0
  33. package/dist/lib/harness-discovery.d.ts.map +1 -0
  34. package/dist/lib/instruction-graph.d.ts +1 -1
  35. package/dist/lib/instruction-graph.d.ts.map +1 -1
  36. package/dist/lib/instruction-source-policy.d.ts +6 -0
  37. package/dist/lib/instruction-source-policy.d.ts.map +1 -0
  38. package/dist/lib/machine.d.ts.map +1 -1
  39. package/dist/lib/managed-skill-runtimes.d.ts +12 -28
  40. package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
  41. package/dist/lib/platform-profiles.d.ts.map +1 -1
  42. package/dist/lib/project-dashboard-standard.d.ts.map +1 -1
  43. package/dist/lib/session-apply.d.ts +35 -0
  44. package/dist/lib/session-apply.d.ts.map +1 -1
  45. package/dist/lib/session-refresh.d.ts +30 -0
  46. package/dist/lib/session-refresh.d.ts.map +1 -0
  47. package/dist/lib/session-render.d.ts +41 -1
  48. package/dist/lib/session-render.d.ts.map +1 -1
  49. package/dist/lib/transforms.d.ts +1 -0
  50. package/dist/lib/transforms.d.ts.map +1 -1
  51. package/dist/mcp/index.js +13 -12
  52. package/dist/mcp/server.d.ts.map +1 -1
  53. package/dist/sdk/index.d.ts +2 -0
  54. package/dist/sdk/index.d.ts.map +1 -1
  55. package/dist/sdk/index.js +172 -0
  56. package/dist/sdk/v1-client.d.ts +7 -1
  57. package/dist/sdk/v1-client.d.ts.map +1 -1
  58. package/dist/sdk/v1.generated.d.ts +26 -0
  59. package/dist/sdk/v1.generated.d.ts.map +1 -1
  60. package/dist/server/index.js +199 -8
  61. package/dist/server/openapi.d.ts +150 -0
  62. package/dist/server/openapi.d.ts.map +1 -1
  63. package/dist/server/v1.d.ts.map +1 -1
  64. package/dist/storage/cloud-store.d.ts.map +1 -1
  65. package/dist/types/index.d.ts +24 -2
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/package.json +1 -1
package/README.md CHANGED
@@ -67,6 +67,19 @@ instructions package-manager-scan --fail-on-findings .
67
67
  instructions package-manager-scan --home --fail-on-findings .
68
68
  ```
69
69
 
70
+ Skills are managed through the Skills CLI. Profile application and bootstrap do
71
+ not inspect, install or repair native Inbox skill payloads, and do not send
72
+ Conversations heartbeats. Their legacy `--from` and `--delivery-verified` flags
73
+ remain accepted for compatibility but perform no verification.
74
+
75
+ `instructions managed-skills status` and `instructions managed-skills apply`
76
+ are deprecated, read-only migration reports. They return a failure when legacy
77
+ Inbox paths remain and preserve those paths, including symlinks. Use the Skills
78
+ CLI to review `skills migrate native`, then sync and load the selected skills.
79
+ An empty legacy inventory does not verify hosted skill selection or runtime
80
+ delivery. The exported inspection/reconciliation helpers behave the same way;
81
+ an explicit legacy `assetPath` no longer enables native payload writes.
82
+
70
83
  Collection commands are compact by default to keep agent terminals and context
71
84
  small. Human output is capped at 20 rows unless you pass `--limit`; use
72
85
  `--cursor` to continue from the next page. Detail is explicit:
@@ -83,6 +96,24 @@ envelope. Its top-level fields are `configs`, `profiles`, `drift`, `secrets`,
83
96
  `secrets.policy` is `redacted_on_ingest`. Run `instructions report` without
84
97
  `--json` for the human-readable report.
85
98
 
99
+ ### Conditional config updates
100
+
101
+ Read the current config version before preparing an edit, then pass that
102
+ `expected_version` to `updateConfig` (store/public SDK), `update_config` (MCP), or:
103
+
104
+ ```bash
105
+ instructions add ./rule.md --kind reference --name example-rule --update --expected-version 7
106
+ ```
107
+
108
+ Guarded clients use `POST /v1/configs/:id/conditional-update`, which requires
109
+ `expected_version`. The generated SDK also exposes `conditionalUpdateConfig` for
110
+ this operation. An older server returns 404 without mutation; clients never fall
111
+ back to an unconditional update. A version mismatch returns HTTP 409 with code
112
+ `CONFIG_VERSION_CONFLICT`, changing neither the config nor its snapshots. Refresh
113
+ and review the newer version before trying again. Calls without a precondition
114
+ retain their existing behavior. New servers also accept `expected_version` on
115
+ PATCH/PUT; use the dedicated conditional route when server capabilities are unknown.
116
+
86
117
  ## Package-Manager Secret Guard
87
118
 
88
119
  `instructions package-manager-scan` blocks package-manager credential ingress without
@@ -361,13 +392,20 @@ upgrade.
361
392
 
362
393
  `instructions session plan` and `instructions session apply` render
363
394
  OpenIdentities and instruction sources into provider-native files for Claude,
364
- Codex, Cursor, OpenCode, Codewith, Qwen, aicopilot, and Google Antigravity.
395
+ Codex, Cursor, OpenCode, Sumi, Codewith, Qwen, aicopilot, and Google Antigravity.
365
396
  The old Google agent target is removed; Antigravity is the only Google coding
366
397
  agent render target. Antigravity workspace rules are rendered to
367
398
  `.agents/rules/*.md`; its current global rules and MCP files use Google's
368
399
  legacy-named `~/.gemini/GEMINI.md` and `~/.gemini/config/mcp_config.json`
369
400
  paths but remain owned by the `antigravity` target.
370
401
 
402
+ Sumi renders one flattened `AGENTS.md`. Pass its actual config directory from
403
+ `sumi debug paths config` as `--target-home`, or use `--project-root` for
404
+ repository instructions. Global plans return `SUMI_CONFIG_DIR`; project plans
405
+ do not change the global config environment. No OpenCode config or fragment
406
+ imports are written. See [session rendering](docs/session-rendering.md) for
407
+ capability limits and examples.
408
+
371
409
  Qwen Code session rendering writes `QWEN.md` instructional context with
372
410
  `QWEN_HOME` pointing at the rendered profile home. Known config sync also
373
411
  tracks Qwen Code `QWEN.md` and `settings.json` files at `~/.qwen/...` and
@@ -536,14 +574,16 @@ and prior on-box-only evidence must be explicitly reconciled before use.
536
574
 
537
575
  ## Machine-aware Profiles
538
576
 
539
- `instructions init` seeds two platform profiles:
577
+ `instructions init` seeds two empty platform profiles:
540
578
 
541
- - `linux-arm64` for `linux-node-a` / `linux-node-b`
542
- - `macos-arm64` for `macos-node-a` / `macos-node-b`
579
+ - `linux-arm64` for Linux arm64
580
+ - `macos-arm64` for macOS arm64
543
581
 
544
- These profiles resolve machine variables like `{{WORKSPACE_ROOT}}`,
545
- `{{BUN_BIN_DIR}}`, `{{BUN_PATH}}`, and `{{PATH_PREFIX}}`, so synced configs can be
546
- portable across Linux and macOS arm64 machines.
582
+ The public presets contain no fleet hostnames or workspace paths. They resolve
583
+ portable tool variables such as `{{BUN_BIN_DIR}}`, `{{BUN_PATH}}`, and
584
+ `{{PATH_PREFIX}}`. Instruction membership is never bulk-copied from the config
585
+ registry; bind reviewed provider/project/role sources explicitly before compiling
586
+ a prompt profile.
547
587
 
548
588
  They also include the project channel variable used by agent-managed project
549
589
  workflows:
@@ -8,10 +8,10 @@ import {
8
8
  getConfigHome,
9
9
  normalizeTargetPath,
10
10
  previewConfigs
11
- } from "./index-ypcef3a2.js";
12
- import"./index-aj66f6xr.js";
11
+ } from "./index-n9arv47w.js";
12
+ import"./index-dwagz53p.js";
13
13
  import"./index-35z65jsa.js";
14
- import"./index-3djthcm6.js";
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-r7nfef2g.js";
12
- import"./index-6jncnnw7.js";
13
- import"./index-n3fjspr0.js";
11
+ } from "./index-6sbmg1vc.js";
12
+ import"./index-enh4yv85.js";
13
+ import"./index-preyvj8n.js";
14
14
  import"./index-fpeyzn3n.js";
15
15
  import"./index-bsan4c16.js";
16
16
  export {
@@ -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 };
@@ -18,11 +18,11 @@ import {
18
18
  resolveProfileVariables,
19
19
  scanSecrets,
20
20
  stampCursorGlobalAuthorityMarker
21
- } from "./index-6jncnnw7.js";
21
+ } from "./index-enh4yv85.js";
22
22
  import {
23
23
  ConfigApplyError,
24
24
  parseTemplateVars
25
- } from "./index-n3fjspr0.js";
25
+ } from "./index-preyvj8n.js";
26
26
 
27
27
  // src/lib/apply.ts
28
28
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "fs";
@@ -529,4 +529,4 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
529
529
  return sessionRenderOwnsPath(normalized);
530
530
  }
531
531
 
532
- export { getConfigHome, expandPath, compactPathForConfigHome, normalizeTargetPath, applyConfig, applyConfigs, applyConfigsWithReport, previewConfigs };
532
+ export { sessionRenderOwnsPath, getConfigHome, expandPath, compactPathForConfigHome, normalizeTargetPath, applyConfig, applyConfigs, applyConfigsWithReport, previewConfigs };
@@ -5,7 +5,7 @@ import {
5
5
  expandPath,
6
6
  getConfigHome,
7
7
  normalizeTargetPath
8
- } from "./index-r7nfef2g.js";
8
+ } from "./index-6sbmg1vc.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-6jncnnw7.js";
19
+ } from "./index-enh4yv85.js";
20
20
 
21
21
  // src/lib/sync.ts
22
22
  import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
@@ -14,8 +14,9 @@ import {
14
14
  ProfileNotFoundError,
15
15
  isTemplate,
16
16
  renderTemplate,
17
- renderTemplatePreview
18
- } from "./index-3djthcm6.js";
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":
@@ -367,6 +373,7 @@ function assetCapability(provider, surface, kind, support, strategies, note, pro
367
373
  var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
368
374
  assetCapability("claude", "code", "skill", "supported", ["emit-file"], "Claude Code project or profile skill files."),
369
375
  assetCapability("claude", "code", "workflow", "supported", ["emit-file"], "Claude Code command and workflow files."),
376
+ assetCapability("claude", "code", "custom-agent", "supported", ["emit-file"], "Claude Code Markdown subagents with native frontmatter in agents/.", ">=2.1.276 <3.0.0"),
370
377
  assetCapability("claude", "code", "hook", "supported", ["emit-file"], "Claude Code hook configuration fragments."),
371
378
  assetCapability("claude", "code", "plugin", "conditional", ["install-marketplace"], "Claude marketplace installation requires an explicit installer."),
372
379
  assetCapability("codex", "cli", "skill", "supported", ["emit-file"], "Codex skill bundle files."),
@@ -377,6 +384,7 @@ var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
377
384
  assetCapability("opencode", "cli", "workflow", "supported", ["emit-file"], "OpenCode command/workflow files."),
378
385
  assetCapability("opencode", "cli", "plugin", "supported", ["emit-file"], "OpenCode local plugin modules."),
379
386
  assetCapability("opencode", "cli", "custom-agent", "supported", ["emit-file"], "OpenCode custom agent files."),
387
+ 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"),
380
388
  assetCapability("codewith", "cli", "skill", "supported", ["emit-file"], "Codewith skill bundle files."),
381
389
  assetCapability("codewith", "cli", "plugin", "conditional", ["install-local", "install-marketplace"], "Codewith plugin installation requires an explicit installer."),
382
390
  assetCapability("aicopilot", "cli", "skill", "supported", ["emit-file"], "AICopilot discovered skill files."),
@@ -409,6 +417,7 @@ var DEFAULT_ASSET_SURFACES = Object.freeze({
409
417
  codex: "cli",
410
418
  cursor: "ide",
411
419
  opencode: "cli",
420
+ sumi: "cli",
412
421
  codewith: "cli",
413
422
  qwen: "cli",
414
423
  aicopilot: "cli",
@@ -458,6 +467,10 @@ function normalizeProfileAssetBinding(value) {
458
467
  const rollback = record["rollback"];
459
468
  if (!ASSET_ROLLBACK_POLICIES.includes(rollback))
460
469
  throw new Error(`Invalid asset rollback policy: ${String(rollback)}`);
470
+ const nativeAgent = record["nativeAgent"] === undefined ? undefined : normalizeNativeAgentMetadata(record["nativeAgent"]);
471
+ if (nativeAgent && (kind !== "custom-agent" || strategy !== "emit-file" || !["claude", "sumi", "opencode"].includes(provider))) {
472
+ throw new Error("nativeAgent metadata requires a supported emitted custom-agent definition.");
473
+ }
461
474
  return {
462
475
  schema: PROFILE_ASSET_BINDING_SCHEMA,
463
476
  assetKey,
@@ -477,10 +490,65 @@ function normalizeProfileAssetBinding(value) {
477
490
  root,
478
491
  relativePath: nonEmptyString(destinationRecord["relativePath"], "destination.relativePath")
479
492
  },
493
+ ...nativeAgent ? { nativeAgent } : {},
480
494
  uninstall,
481
495
  rollback
482
496
  };
483
497
  }
498
+ function normalizeNativeAgentMetadata(value) {
499
+ const record = objectRecord(value, "nativeAgent");
500
+ if (Object.keys(record).some((key) => !["name", "description", "frontmatter"].includes(key)))
501
+ throw new Error("Unknown nativeAgent metadata field.");
502
+ const name = nonEmptyString(record["name"], "nativeAgent.name");
503
+ const description = nonEmptyString(record["description"], "nativeAgent.description");
504
+ if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(name) || name.length > 128)
505
+ throw new Error("Invalid nativeAgent.name.");
506
+ if (description.length > 4096 || /[\r\n\0]/.test(description))
507
+ throw new Error("Invalid nativeAgent.description.");
508
+ if (record["frontmatter"] === undefined)
509
+ return { name, description };
510
+ const frontmatter = record["frontmatter"];
511
+ if (typeof frontmatter !== "string" || frontmatter.length > 16384 || frontmatter.includes("\x00"))
512
+ throw new Error("Invalid nativeAgent.frontmatter.");
513
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n$/.exec(frontmatter);
514
+ if (!match)
515
+ throw new Error("nativeAgent.frontmatter requires one complete newline-terminated YAML header.");
516
+ const scalar = (raw) => {
517
+ if (raw.startsWith('"')) {
518
+ try {
519
+ const parsed = JSON.parse(raw);
520
+ return typeof parsed === "string" ? parsed : undefined;
521
+ } catch {
522
+ return;
523
+ }
524
+ }
525
+ if (!/^[A-Za-z0-9][A-Za-z0-9 _.,:;()/?@+-]*$/.test(raw) || /:(?:\s|$)/.test(raw))
526
+ return;
527
+ if (/^(?:true|yes|on|y)$/i.test(raw))
528
+ return true;
529
+ if (/^(?:false|no|off|n)$/i.test(raw))
530
+ return false;
531
+ if (/^null$/i.test(raw))
532
+ return null;
533
+ if (/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(raw))
534
+ return Number(raw);
535
+ if (/^[0-9]/.test(raw))
536
+ return;
537
+ return raw;
538
+ };
539
+ const fields = new Map;
540
+ for (const line of match[1].split(/\r?\n/)) {
541
+ if (!line.trim() || line.startsWith("#"))
542
+ continue;
543
+ const field = /^([A-Za-z][A-Za-z0-9_-]*):[ \t]+(.+)$/.exec(line);
544
+ if (!field || fields.has(field[1]) || scalar(field[2]) === undefined)
545
+ throw new Error("nativeAgent.frontmatter requires unambiguous, unique flat scalar fields.");
546
+ fields.set(field[1], scalar(field[2]));
547
+ }
548
+ if (fields.get("name") !== name || fields.get("description") !== description)
549
+ throw new Error("nativeAgent.frontmatter name and description must match explicit metadata.");
550
+ return { name, description, frontmatter };
551
+ }
484
552
  function parseJson(value) {
485
553
  try {
486
554
  return JSON.parse(value);
@@ -534,6 +602,7 @@ var DEFAULT_PROVIDER_CAPABILITIES = Object.freeze({
534
602
  codex: capability("codex", ">=0.1.0", "flattened", "AGENTS.md", { asset_surface: "cli" }),
535
603
  cursor: capability("cursor", ">=1.0.0", "cursor-rule", ".cursor/rules/*.mdc", { activation_modes: ["always", "glob"], conditional_artifacts: true, asset_surface: "ide" }),
536
604
  opencode: capability("opencode", ">=1.0.0", "managed-fragment", "opencode.json instructions", { provider_variant: "v1-instructions", session_surface: "opencode-config-instructions" }),
605
+ sumi: capability("sumi", ">=0.2.22 <0.3.0", "flattened", "AGENTS.md"),
537
606
  codewith: capability("codewith", ">=0.1.0", "flattened", "CODEWITH.md"),
538
607
  qwen: capability("qwen", ">=0.1.0", "flattened", "QWEN.md"),
539
608
  aicopilot: capability("aicopilot", ">=0.1.0", "flattened", "AICOPILOT.md"),
@@ -2115,7 +2184,7 @@ function isNotFoundHttpError2(err) {
2115
2184
  var localStoreModulePromise = null;
2116
2185
  function localStoreModule() {
2117
2186
  if (!localStoreModulePromise)
2118
- localStoreModulePromise = import("./local-0a9gja58.js");
2187
+ localStoreModulePromise = import("./local-5dsm856v.js");
2119
2188
  return localStoreModulePromise;
2120
2189
  }
2121
2190
 
@@ -2396,7 +2465,9 @@ class CloudConfigStore {
2396
2465
  return data.config;
2397
2466
  }
2398
2467
  async updateConfig(idOrSlug, input) {
2399
- const { data } = await this.request("PATCH", `/configs/${encodeURIComponent(idOrSlug)}`, input);
2468
+ validateExpectedConfigVersion(input.expected_version);
2469
+ const conditional = input.expected_version !== undefined;
2470
+ const { data } = await this.request(conditional ? "POST" : "PATCH", `/configs/${encodeURIComponent(idOrSlug)}${conditional ? "/conditional-update" : ""}`, input);
2400
2471
  return data.config;
2401
2472
  }
2402
2473
  async deleteConfig(idOrSlug) {
@@ -2473,7 +2544,7 @@ class CloudConfigStore {
2473
2544
  throw new ProfileNotFoundError(idOrSlug);
2474
2545
  return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
2475
2546
  }
2476
- async getProfileConfigBindings(idOrSlug) {
2547
+ async getProfileConfigBindings(idOrSlug, options = {}) {
2477
2548
  let routeMissing = false;
2478
2549
  const bindings = await aggregateBoundedCollection("profile config bindings", async (cursor) => {
2479
2550
  const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
@@ -2486,6 +2557,8 @@ class CloudConfigStore {
2486
2557
  }, (binding) => `${binding.profile_id}\x00${binding.config_id}`);
2487
2558
  if (!routeMissing)
2488
2559
  return bindings;
2560
+ if (options.requireExplicit)
2561
+ throw new Error("HOSTED_BINDINGS_REQUIRED: profile config binding route is unavailable; refusing legacy activation fallback.");
2489
2562
  const profile = await this.getProfile(idOrSlug);
2490
2563
  const configs = await this.getProfileConfigs(idOrSlug);
2491
2564
  return configs.map((config, sort_order) => ({
@@ -2550,7 +2623,7 @@ class CloudConfigStore {
2550
2623
  async removeConfigFromProfile(profileIdOrSlug, configId) {
2551
2624
  await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
2552
2625
  }
2553
- async getProfileAssetBindings(profileIdOrSlug) {
2626
+ async getProfileAssetBindings(profileIdOrSlug, options = {}) {
2554
2627
  let routeMissing = false;
2555
2628
  const assets = await aggregateBoundedCollection("profile asset bindings", async (cursor) => {
2556
2629
  const normalized = normalizeBoundedReadOptions({ limit: 100, cursor });
@@ -2563,6 +2636,8 @@ class CloudConfigStore {
2563
2636
  }, (asset) => `${asset.profile_id}\x00${asset.binding.assetKey}`);
2564
2637
  if (!routeMissing)
2565
2638
  return assets;
2639
+ if (options.requireExplicit)
2640
+ throw new Error("HOSTED_ASSETS_REQUIRED: profile asset binding route is unavailable; refusing an empty asset fallback.");
2566
2641
  await this.getProfile(profileIdOrSlug);
2567
2642
  return [];
2568
2643
  }
@@ -7199,6 +7274,15 @@ var SESSION_TOOL_ADAPTERS = {
7199
7274
  description: "OpenCode AGENTS.md plus opencode.json instructions pointing at managed fragments.",
7200
7275
  providerSurface: "legacy-dual"
7201
7276
  },
7277
+ sumi: {
7278
+ tool: "sumi",
7279
+ mode: "flattened-markdown",
7280
+ indexFile: "AGENTS.md",
7281
+ managedDir: SESSION_RENDER_INSTRUCTIONS_MANAGED_DIR,
7282
+ envVar: "SUMI_CONFIG_DIR",
7283
+ nativeImports: false,
7284
+ description: "Sumi native AGENTS.md in the explicit resolved config directory or project root."
7285
+ },
7202
7286
  aicopilot: {
7203
7287
  tool: "aicopilot",
7204
7288
  mode: "flattened-markdown",
@@ -7321,7 +7405,7 @@ function detectMachineContext(overrides = {}) {
7321
7405
  created_at: "",
7322
7406
  os_family: osFamily,
7323
7407
  home_dir: homeDir4,
7324
- workspace_root: overrides.workspace_root ?? join5(homeDir4, osFamily === "macos" ? "Workspace" : "workspace"),
7408
+ workspace_root: overrides.workspace_root ?? "",
7325
7409
  bun_bin_dir: bunBinDir,
7326
7410
  bun_path: overrides.bun_path ?? defaultBunPath,
7327
7411
  path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join5("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
@@ -7334,7 +7418,7 @@ function machineContextToVariables(machine) {
7334
7418
  OS_FAMILY: machine.os_family,
7335
7419
  ARCH: machine.arch ?? "",
7336
7420
  HOME_DIR: machine.home_dir,
7337
- WORKSPACE_ROOT: machine.workspace_root,
7421
+ ...machine.workspace_root ? { WORKSPACE_ROOT: machine.workspace_root } : {},
7338
7422
  BUN_BIN_DIR: machine.bun_bin_dir,
7339
7423
  BUN_PATH: machine.bun_path,
7340
7424
  PATH_PREFIX: machine.path_prefix