@hasna/instructions 0.7.2 → 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 (41) hide show
  1. package/README.md +13 -0
  2. package/dist/chunks/{apply-ps6jjt6k.js → apply-1gyr8r0x.js} +2 -2
  3. package/dist/chunks/{apply-wj7wh5km.js → apply-fyfzqc7s.js} +2 -2
  4. package/dist/chunks/{index-y8410ve0.js → index-6sbmg1vc.js} +1 -1
  5. package/dist/chunks/{index-18j7x3xw.js → index-axs3yftz.js} +2 -2
  6. package/dist/chunks/{index-pq18fdbj.js → index-dwagz53p.js} +64 -3
  7. package/dist/chunks/{index-n6nh6f5r.js → index-enh4yv85.js} +156 -15
  8. package/dist/chunks/{index-ape24zc0.js → index-n9arv47w.js} +1 -1
  9. package/dist/chunks/{index-ek15201v.js → index-z27xp7fh.js} +2 -2
  10. package/dist/chunks/{local-1c1qxzvx.js → local-5dsm856v.js} +1 -1
  11. package/dist/chunks/{local-hc67bynj.js → local-yxsbs8x3.js} +1 -1
  12. package/dist/chunks/{sync-azd9t4p8.js → sync-6r1v8hd3.js} +3 -3
  13. package/dist/chunks/{sync-12m3vs6g.js → sync-k3pab4s6.js} +3 -3
  14. package/dist/cli/index.js +526 -555
  15. package/dist/index.d.ts +4 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +690 -587
  18. package/dist/lib/asset-plan.d.ts +4 -1
  19. package/dist/lib/asset-plan.d.ts.map +1 -1
  20. package/dist/lib/harness-discovery.d.ts +52 -0
  21. package/dist/lib/harness-discovery.d.ts.map +1 -0
  22. package/dist/lib/machine.d.ts.map +1 -1
  23. package/dist/lib/managed-skill-runtimes.d.ts +12 -28
  24. package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
  25. package/dist/lib/session-apply.d.ts +11 -0
  26. package/dist/lib/session-apply.d.ts.map +1 -1
  27. package/dist/lib/session-refresh.d.ts.map +1 -1
  28. package/dist/lib/session-render.d.ts +7 -0
  29. package/dist/lib/session-render.d.ts.map +1 -1
  30. package/dist/mcp/index.js +7 -7
  31. package/dist/sdk/index.d.ts +2 -0
  32. package/dist/sdk/index.d.ts.map +1 -1
  33. package/dist/sdk/index.js +153 -0
  34. package/dist/sdk/v1.generated.d.ts +6 -0
  35. package/dist/sdk/v1.generated.d.ts.map +1 -1
  36. package/dist/server/index.js +77 -0
  37. package/dist/server/openapi.d.ts +27 -0
  38. package/dist/server/openapi.d.ts.map +1 -1
  39. package/dist/types/index.d.ts +8 -0
  40. package/dist/types/index.d.ts.map +1 -1
  41. 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:
@@ -8,8 +8,8 @@ import {
8
8
  getConfigHome,
9
9
  normalizeTargetPath,
10
10
  previewConfigs
11
- } from "./index-ape24zc0.js";
12
- import"./index-pq18fdbj.js";
11
+ } from "./index-n9arv47w.js";
12
+ import"./index-dwagz53p.js";
13
13
  import"./index-35z65jsa.js";
14
14
  import"./index-27az1qb1.js";
15
15
  import"./index-nnwp92tk.js";
@@ -8,8 +8,8 @@ import {
8
8
  getConfigHome,
9
9
  normalizeTargetPath,
10
10
  previewConfigs
11
- } from "./index-y8410ve0.js";
12
- import"./index-n6nh6f5r.js";
11
+ } from "./index-6sbmg1vc.js";
12
+ import"./index-enh4yv85.js";
13
13
  import"./index-preyvj8n.js";
14
14
  import"./index-fpeyzn3n.js";
15
15
  import"./index-bsan4c16.js";
@@ -18,7 +18,7 @@ import {
18
18
  resolveProfileVariables,
19
19
  scanSecrets,
20
20
  stampCursorGlobalAuthorityMarker
21
- } from "./index-n6nh6f5r.js";
21
+ } from "./index-enh4yv85.js";
22
22
  import {
23
23
  ConfigApplyError,
24
24
  parseTemplateVars
@@ -5,7 +5,7 @@ import {
5
5
  expandPath,
6
6
  getConfigHome,
7
7
  normalizeTargetPath
8
- } from "./index-y8410ve0.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-n6nh6f5r.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";
@@ -373,6 +373,7 @@ function assetCapability(provider, surface, kind, support, strategies, note, pro
373
373
  var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
374
374
  assetCapability("claude", "code", "skill", "supported", ["emit-file"], "Claude Code project or profile skill files."),
375
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"),
376
377
  assetCapability("claude", "code", "hook", "supported", ["emit-file"], "Claude Code hook configuration fragments."),
377
378
  assetCapability("claude", "code", "plugin", "conditional", ["install-marketplace"], "Claude marketplace installation requires an explicit installer."),
378
379
  assetCapability("codex", "cli", "skill", "supported", ["emit-file"], "Codex skill bundle files."),
@@ -383,6 +384,7 @@ var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
383
384
  assetCapability("opencode", "cli", "workflow", "supported", ["emit-file"], "OpenCode command/workflow files."),
384
385
  assetCapability("opencode", "cli", "plugin", "supported", ["emit-file"], "OpenCode local plugin modules."),
385
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"),
386
388
  assetCapability("codewith", "cli", "skill", "supported", ["emit-file"], "Codewith skill bundle files."),
387
389
  assetCapability("codewith", "cli", "plugin", "conditional", ["install-local", "install-marketplace"], "Codewith plugin installation requires an explicit installer."),
388
390
  assetCapability("aicopilot", "cli", "skill", "supported", ["emit-file"], "AICopilot discovered skill files."),
@@ -465,6 +467,10 @@ function normalizeProfileAssetBinding(value) {
465
467
  const rollback = record["rollback"];
466
468
  if (!ASSET_ROLLBACK_POLICIES.includes(rollback))
467
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
+ }
468
474
  return {
469
475
  schema: PROFILE_ASSET_BINDING_SCHEMA,
470
476
  assetKey,
@@ -484,10 +490,65 @@ function normalizeProfileAssetBinding(value) {
484
490
  root,
485
491
  relativePath: nonEmptyString(destinationRecord["relativePath"], "destination.relativePath")
486
492
  },
493
+ ...nativeAgent ? { nativeAgent } : {},
487
494
  uninstall,
488
495
  rollback
489
496
  };
490
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
+ }
491
552
  function parseJson(value) {
492
553
  try {
493
554
  return JSON.parse(value);
@@ -2123,7 +2184,7 @@ function isNotFoundHttpError2(err) {
2123
2184
  var localStoreModulePromise = null;
2124
2185
  function localStoreModule() {
2125
2186
  if (!localStoreModulePromise)
2126
- localStoreModulePromise = import("./local-1c1qxzvx.js");
2187
+ localStoreModulePromise = import("./local-5dsm856v.js");
2127
2188
  return localStoreModulePromise;
2128
2189
  }
2129
2190
 
@@ -7344,7 +7405,7 @@ function detectMachineContext(overrides = {}) {
7344
7405
  created_at: "",
7345
7406
  os_family: osFamily,
7346
7407
  home_dir: homeDir4,
7347
- workspace_root: overrides.workspace_root ?? join5(homeDir4, osFamily === "macos" ? "Workspace" : "workspace"),
7408
+ workspace_root: overrides.workspace_root ?? "",
7348
7409
  bun_bin_dir: bunBinDir,
7349
7410
  bun_path: overrides.bun_path ?? defaultBunPath,
7350
7411
  path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join5("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
@@ -7357,7 +7418,7 @@ function machineContextToVariables(machine) {
7357
7418
  OS_FAMILY: machine.os_family,
7358
7419
  ARCH: machine.arch ?? "",
7359
7420
  HOME_DIR: machine.home_dir,
7360
- WORKSPACE_ROOT: machine.workspace_root,
7421
+ ...machine.workspace_root ? { WORKSPACE_ROOT: machine.workspace_root } : {},
7361
7422
  BUN_BIN_DIR: machine.bun_bin_dir,
7362
7423
  BUN_PATH: machine.bun_path,
7363
7424
  PATH_PREFIX: machine.path_prefix
@@ -7510,6 +7510,7 @@ function assetCapability(provider, surface, kind, support, strategies, note, pro
7510
7510
  var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
7511
7511
  assetCapability("claude", "code", "skill", "supported", ["emit-file"], "Claude Code project or profile skill files."),
7512
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"),
7513
7514
  assetCapability("claude", "code", "hook", "supported", ["emit-file"], "Claude Code hook configuration fragments."),
7514
7515
  assetCapability("claude", "code", "plugin", "conditional", ["install-marketplace"], "Claude marketplace installation requires an explicit installer."),
7515
7516
  assetCapability("codex", "cli", "skill", "supported", ["emit-file"], "Codex skill bundle files."),
@@ -7520,6 +7521,7 @@ var ASSET_CAPABILITY_DESCRIPTORS = Object.freeze([
7520
7521
  assetCapability("opencode", "cli", "workflow", "supported", ["emit-file"], "OpenCode command/workflow files."),
7521
7522
  assetCapability("opencode", "cli", "plugin", "supported", ["emit-file"], "OpenCode local plugin modules."),
7522
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"),
7523
7525
  assetCapability("codewith", "cli", "skill", "supported", ["emit-file"], "Codewith skill bundle files."),
7524
7526
  assetCapability("codewith", "cli", "plugin", "conditional", ["install-local", "install-marketplace"], "Codewith plugin installation requires an explicit installer."),
7525
7527
  assetCapability("aicopilot", "cli", "skill", "supported", ["emit-file"], "AICopilot discovered skill files."),
@@ -7623,6 +7625,10 @@ function normalizeProfileAssetBinding(value) {
7623
7625
  const rollback = record["rollback"];
7624
7626
  if (!ASSET_ROLLBACK_POLICIES.includes(rollback))
7625
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
+ }
7626
7632
  return {
7627
7633
  schema: PROFILE_ASSET_BINDING_SCHEMA,
7628
7634
  assetKey,
@@ -7642,6 +7648,7 @@ function normalizeProfileAssetBinding(value) {
7642
7648
  root,
7643
7649
  relativePath: nonEmptyString(destinationRecord["relativePath"], "destination.relativePath")
7644
7650
  },
7651
+ ...nativeAgent ? { nativeAgent } : {},
7645
7652
  uninstall,
7646
7653
  rollback
7647
7654
  };
@@ -7717,6 +7724,7 @@ function compileAssetPlan(input) {
7717
7724
  allowed: binding.source.allowed
7718
7725
  },
7719
7726
  destination: binding.destination,
7727
+ ...binding.nativeAgent ? { nativeAgent: binding.nativeAgent } : {},
7720
7728
  support,
7721
7729
  action,
7722
7730
  mutationMode: input.mode,
@@ -7781,6 +7789,18 @@ function validateAssetSourceAndDestination(bundle, binding, diagnostics) {
7781
7789
  pathSafe = false;
7782
7790
  diagnostics.push(diagnostic("error", "ASSET_DESTINATION_UNSAFE", binding.assetKey, error.message));
7783
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
+ }
7784
7804
  const expectedLocator = bundle.locator;
7785
7805
  if (!binding.source.immutable || binding.source.locator !== expectedLocator) {
7786
7806
  diagnostics.push(diagnostic("error", "ASSET_SOURCE_MUTABLE_OR_UNPINNED", binding.assetKey, `Asset source must be pinned to ${expectedLocator}.`));
@@ -7836,6 +7856,72 @@ function safeRelativePath(value) {
7836
7856
  }
7837
7857
  return normalized;
7838
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
+ }
7839
7925
  function diagnostic(severity, code, assetKey, message) {
7840
7926
  return { severity, code, assetKey, message };
7841
7927
  }
@@ -9066,7 +9152,7 @@ function buildCursorRuleFiles(targetHome, adapter, sources) {
9066
9152
  return [sourceFile, ...ruleFiles];
9067
9153
  });
9068
9154
  }
9069
- function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig) {
9155
+ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig, projectRoot) {
9070
9156
  const surface = adapter.providerSurface ?? "legacy-dual";
9071
9157
  const fragments = sources.flatMap((source, index) => [
9072
9158
  makeFile(targetHome, fragmentPath(adapter, index, source), "fragment", sectionForSource(source), [source.id]),
@@ -9086,13 +9172,13 @@ function buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfi
9086
9172
  ]);
9087
9173
  const existingConfigPath = joinTarget(targetHome, adapter.configFile);
9088
9174
  const selectedConfig = existsSync4(existingConfigPath) ? readOpenCodeConfig(readFileSync4(existingConfigPath, "utf8"), existingConfigPath) : providerConfig ? readOpenCodeConfig(providerConfig.content, providerConfig.sourceId) : {};
9089
- 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));
9090
9176
  const config = {
9091
9177
  ...selectedConfig,
9092
9178
  $schema: typeof selectedConfig["$schema"] === "string" ? selectedConfig["$schema"] : "https://opencode.ai/config.json",
9093
9179
  instructions: [
9094
9180
  ...preservedInstructions,
9095
- ...fragments.map((file) => file.relativePath)
9181
+ ...fragments.map((file) => file.path)
9096
9182
  ]
9097
9183
  };
9098
9184
  const configSourceIds = [
@@ -9135,9 +9221,62 @@ function normalizeOpenCodeInstructions(value) {
9135
9221
  }
9136
9222
  return value;
9137
9223
  }
9138
- function pathIsManagedOpenCodeInstruction(path, managedDir) {
9139
- const normalized = posix2.normalize(path.replaceAll("\\", "/")).replace(/^\.\//, "");
9140
- return normalized === managedDir || normalized.startsWith(`${managedDir}/`);
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;
9141
9280
  }
9142
9281
  function buildAntigravityRuleFiles(targetHome, adapter, sources) {
9143
9282
  return sources.flatMap((source, index) => {
@@ -9191,7 +9330,7 @@ function makeAntigravityRuleFile(targetHome, relativePath, content, sourceIds) {
9191
9330
  }
9192
9331
  return file;
9193
9332
  }
9194
- function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion) {
9333
+ function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion, projectRoot) {
9195
9334
  switch (adapter.mode) {
9196
9335
  case "native-imports":
9197
9336
  return buildNativeImportFiles(targetHome, adapter, profile, sources, providerVersion);
@@ -9200,7 +9339,7 @@ function buildFiles(targetHome, adapter, profile, sources, providerConfig, provi
9200
9339
  case "cursor-mdc":
9201
9340
  return buildCursorRuleFiles(targetHome, adapter, sources);
9202
9341
  case "opencode-instructions":
9203
- return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig);
9342
+ return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig, projectRoot);
9204
9343
  case "antigravity-rules":
9205
9344
  return buildAntigravityRuleFiles(targetHome, adapter, sources);
9206
9345
  case "provider-rules":
@@ -9229,12 +9368,13 @@ function buildAssetFiles(input, targetHome, blocked) {
9229
9368
  if (!relativePath || relativePath === ".." || relativePath.startsWith("../") || isAbsolute3(relativePath)) {
9230
9369
  throw new Error(`Asset ${item.assetKey} is outside the session snapshot root; use a project-scoped session plan for atomic application.`);
9231
9370
  }
9371
+ const renderedContent = renderNativeAgentContent(content, item.nativeAgent);
9232
9372
  return {
9233
9373
  path,
9234
9374
  relativePath: assertSafeRelativePath(relativePath),
9235
9375
  role: "asset",
9236
- content,
9237
- sha256: sha2565(content),
9376
+ content: renderedContent,
9377
+ sha256: sha2565(renderedContent),
9238
9378
  sourceIds: [item.sourceConfigId, item.assetId]
9239
9379
  };
9240
9380
  });
@@ -9413,7 +9553,7 @@ function resolveSessionTargetOwnership(input, target) {
9413
9553
  tool: input.tool,
9414
9554
  profile: input.profile,
9415
9555
  targetHome: target.targetHome,
9416
- projectRoot: null,
9556
+ projectRoot: input.tool === "opencode" && input.projectRoot ? resolveSessionPath(input.projectRoot) : null,
9417
9557
  ownedBy: "open-configs",
9418
9558
  canonicalOwner: "instructions",
9419
9559
  writer: {
@@ -9474,7 +9614,7 @@ function planSessionRender(input) {
9474
9614
  if (input.providerConfig && input.tool !== "opencode") {
9475
9615
  throw new Error("Provider base config is supported only for OpenCode session renders.");
9476
9616
  }
9477
- 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);
9478
9618
  const projectContext = blocked ? null : composeProjectContextSessionRender({
9479
9619
  tool: input.tool,
9480
9620
  adapter_mode: adapter.mode,
@@ -9575,6 +9715,7 @@ function planSessionRender(input) {
9575
9715
  mutationMode: item.mutationMode,
9576
9716
  destination: item.destination,
9577
9717
  digest: item.source.digest,
9718
+ ...item.nativeAgent ? { nativeAgent: item.nativeAgent } : {},
9578
9719
  exactOnceKey: item.exactOnceKey
9579
9720
  }))
9580
9721
  }
@@ -11911,7 +12052,7 @@ function formatCliError(err, env = process.env) {
11911
12052
  var localStoreModulePromise = null;
11912
12053
  function localStoreModule() {
11913
12054
  if (!localStoreModulePromise)
11914
- localStoreModulePromise = import("./local-hc67bynj.js");
12055
+ localStoreModulePromise = import("./local-yxsbs8x3.js");
11915
12056
  return localStoreModulePromise;
11916
12057
  }
11917
12058
 
@@ -12723,7 +12864,7 @@ function detectMachineContext(overrides = {}) {
12723
12864
  created_at: "",
12724
12865
  os_family: osFamily,
12725
12866
  home_dir: homeDir4,
12726
- workspace_root: overrides.workspace_root ?? join7(homeDir4, osFamily === "macos" ? "Workspace" : "workspace"),
12867
+ workspace_root: overrides.workspace_root ?? "",
12727
12868
  bun_bin_dir: bunBinDir,
12728
12869
  bun_path: overrides.bun_path ?? defaultBunPath,
12729
12870
  path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join7("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
@@ -12736,7 +12877,7 @@ function machineContextToVariables(machine) {
12736
12877
  OS_FAMILY: machine.os_family,
12737
12878
  ARCH: machine.arch ?? "",
12738
12879
  HOME_DIR: machine.home_dir,
12739
- WORKSPACE_ROOT: machine.workspace_root,
12880
+ ...machine.workspace_root ? { WORKSPACE_ROOT: machine.workspace_root } : {},
12740
12881
  BUN_BIN_DIR: machine.bun_bin_dir,
12741
12882
  BUN_PATH: machine.bun_path,
12742
12883
  PATH_PREFIX: machine.path_prefix
@@ -15,7 +15,7 @@ import {
15
15
  resolveConfigStore,
16
16
  resolveProfileVariables,
17
17
  stampCursorGlobalAuthorityMarker
18
- } from "./index-pq18fdbj.js";
18
+ } from "./index-dwagz53p.js";
19
19
  import {
20
20
  isSecretVarName,
21
21
  redactFormatForTarget,
@@ -5,7 +5,7 @@ import {
5
5
  expandPath,
6
6
  getConfigHome,
7
7
  normalizeTargetPath
8
- } from "./index-ape24zc0.js";
8
+ } from "./index-n9arv47w.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-pq18fdbj.js";
16
+ } from "./index-dwagz53p.js";
17
17
  import {
18
18
  isSecretVarName,
19
19
  redactContent,
@@ -14,7 +14,7 @@ import {
14
14
  normalizeOsFamily,
15
15
  normalizeProfileAssetBinding,
16
16
  normalizeProfileConfigBinding
17
- } from "./index-pq18fdbj.js";
17
+ } from "./index-dwagz53p.js";
18
18
  import"./index-35z65jsa.js";
19
19
  import {
20
20
  ConfigNotFoundError,
@@ -7,7 +7,7 @@ import {
7
7
  normalizeOsFamily,
8
8
  normalizeProfileAssetBinding,
9
9
  normalizeProfileConfigBinding
10
- } from "./index-n6nh6f5r.js";
10
+ } from "./index-enh4yv85.js";
11
11
  import {
12
12
  ConfigNotFoundError,
13
13
  ConfigVersionConflictError,
@@ -12,9 +12,9 @@ import {
12
12
  syncProject,
13
13
  syncToDir,
14
14
  syncToDisk
15
- } from "./index-18j7x3xw.js";
16
- import"./index-y8410ve0.js";
17
- import"./index-n6nh6f5r.js";
15
+ } from "./index-axs3yftz.js";
16
+ import"./index-6sbmg1vc.js";
17
+ import"./index-enh4yv85.js";
18
18
  import"./index-preyvj8n.js";
19
19
  import"./index-fpeyzn3n.js";
20
20
  import"./index-bsan4c16.js";
@@ -12,9 +12,9 @@ import {
12
12
  syncProject,
13
13
  syncToDir,
14
14
  syncToDisk
15
- } from "./index-ek15201v.js";
16
- import"./index-ape24zc0.js";
17
- import"./index-pq18fdbj.js";
15
+ } from "./index-z27xp7fh.js";
16
+ import"./index-n9arv47w.js";
17
+ import"./index-dwagz53p.js";
18
18
  import"./index-35z65jsa.js";
19
19
  import"./index-27az1qb1.js";
20
20
  import"./index-nnwp92tk.js";