@hasna/instructions 0.7.2 → 0.7.5
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 +13 -0
- package/dist/chunks/{apply-wj7wh5km.js → apply-1cpkx082.js} +2 -2
- package/dist/chunks/{apply-ps6jjt6k.js → apply-xraar7p0.js} +2 -2
- package/dist/chunks/{index-pq18fdbj.js → index-16j8x10s.js} +64 -3
- package/dist/chunks/{index-n6nh6f5r.js → index-6qfy0542.js} +193 -15
- package/dist/chunks/{index-ek15201v.js → index-rvb4znxa.js} +2 -2
- package/dist/chunks/{index-ape24zc0.js → index-src5t3my.js} +1 -1
- package/dist/chunks/{index-y8410ve0.js → index-x0v4m19f.js} +1 -1
- package/dist/chunks/{index-18j7x3xw.js → index-ysnp8y58.js} +2 -2
- package/dist/chunks/{local-1c1qxzvx.js → local-66fck74w.js} +1 -1
- package/dist/chunks/{local-hc67bynj.js → local-jqfx3kbq.js} +1 -1
- package/dist/chunks/{sync-azd9t4p8.js → sync-8763n4sc.js} +3 -3
- package/dist/chunks/{sync-12m3vs6g.js → sync-8ca3ew84.js} +3 -3
- package/dist/cli/index.js +526 -554
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +727 -587
- package/dist/lib/asset-plan.d.ts +4 -1
- package/dist/lib/asset-plan.d.ts.map +1 -1
- package/dist/lib/harness-discovery.d.ts +52 -0
- package/dist/lib/harness-discovery.d.ts.map +1 -0
- package/dist/lib/machine.d.ts.map +1 -1
- package/dist/lib/managed-skill-runtimes.d.ts +12 -28
- package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
- package/dist/lib/session-apply.d.ts +11 -0
- package/dist/lib/session-apply.d.ts.map +1 -1
- package/dist/lib/session-refresh.d.ts.map +1 -1
- package/dist/lib/session-render.d.ts +7 -0
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/mcp/index.js +7 -7
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +153 -0
- package/dist/sdk/v1.generated.d.ts +6 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +77 -0
- package/dist/server/openapi.d.ts +27 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- 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-
|
|
12
|
-
import"./index-
|
|
11
|
+
} from "./index-x0v4m19f.js";
|
|
12
|
+
import"./index-6qfy0542.js";
|
|
13
13
|
import"./index-preyvj8n.js";
|
|
14
14
|
import"./index-fpeyzn3n.js";
|
|
15
15
|
import"./index-bsan4c16.js";
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
getConfigHome,
|
|
9
9
|
normalizeTargetPath,
|
|
10
10
|
previewConfigs
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
11
|
+
} from "./index-src5t3my.js";
|
|
12
|
+
import"./index-16j8x10s.js";
|
|
13
13
|
import"./index-35z65jsa.js";
|
|
14
14
|
import"./index-27az1qb1.js";
|
|
15
15
|
import"./index-nnwp92tk.js";
|
|
@@ -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-
|
|
2187
|
+
localStoreModulePromise = import("./local-66fck74w.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 ??
|
|
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.
|
|
9181
|
+
...fragments.map((file) => file.path)
|
|
9096
9182
|
]
|
|
9097
9183
|
};
|
|
9098
9184
|
const configSourceIds = [
|
|
@@ -9135,9 +9221,99 @@ function normalizeOpenCodeInstructions(value) {
|
|
|
9135
9221
|
}
|
|
9136
9222
|
return value;
|
|
9137
9223
|
}
|
|
9138
|
-
function pathIsManagedOpenCodeInstruction(
|
|
9139
|
-
const
|
|
9140
|
-
|
|
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) => {
|
|
9228
|
+
const path = candidate.caseInsensitive ? candidate.path.toLowerCase() : candidate.path;
|
|
9229
|
+
const namespace = candidate.caseInsensitive ? normalizedManagedDir.toLowerCase() : normalizedManagedDir;
|
|
9230
|
+
return path === namespace || path.endsWith(`/${namespace}`) || path.includes(`/${namespace}/`);
|
|
9231
|
+
});
|
|
9232
|
+
}
|
|
9233
|
+
function canonicalOpenCodeInstructionPaths(reference, targetHome, projectRoot) {
|
|
9234
|
+
const decodedReference = decodeOpenCodePathEscapes(reference);
|
|
9235
|
+
const portable = decodedReference.replaceAll("\\", "/");
|
|
9236
|
+
if (portable.includes("\x00")) {
|
|
9237
|
+
throw new Error("OpenCode config instruction references cannot contain NUL bytes.");
|
|
9238
|
+
}
|
|
9239
|
+
if (/^[A-Za-z]:(?!\/)/.test(portable)) {
|
|
9240
|
+
throw new Error("OpenCode config instruction references cannot use Win32 drive-relative paths.");
|
|
9241
|
+
}
|
|
9242
|
+
const windowsAbsolute = /^[A-Za-z]:\//.test(portable);
|
|
9243
|
+
const uncAbsolute = portable.startsWith("//");
|
|
9244
|
+
const windowsRootRelative = /^\\(?![\\/])/.test(decodedReference);
|
|
9245
|
+
const uriScheme = windowsAbsolute || uncAbsolute || windowsRootRelative ? null : /^([A-Za-z][A-Za-z0-9+.-]*):/.exec(portable)?.[1]?.toLowerCase();
|
|
9246
|
+
if (uriScheme && uriScheme !== "file")
|
|
9247
|
+
return [];
|
|
9248
|
+
if (uriScheme === "file") {
|
|
9249
|
+
const fileReference = reference.replaceAll("\\", "/");
|
|
9250
|
+
if (!/^file:\/\//i.test(fileReference)) {
|
|
9251
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9252
|
+
}
|
|
9253
|
+
let url;
|
|
9254
|
+
try {
|
|
9255
|
+
url = new URL(fileReference);
|
|
9256
|
+
} catch {
|
|
9257
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9258
|
+
}
|
|
9259
|
+
if (url.protocol !== "file:" || url.username || url.password || url.port || url.search || url.hash) {
|
|
9260
|
+
throw new Error("OpenCode config contains an invalid file URL instruction reference.");
|
|
9261
|
+
}
|
|
9262
|
+
const pathname = decodeOpenCodePathEscapes(url.pathname).replaceAll("\\", "/");
|
|
9263
|
+
if (pathname.includes("\x00")) {
|
|
9264
|
+
throw new Error("OpenCode config instruction references cannot contain NUL bytes.");
|
|
9265
|
+
}
|
|
9266
|
+
if (/^\/[A-Za-z]:(?!\/)/.test(pathname)) {
|
|
9267
|
+
throw new Error("OpenCode config instruction references cannot use Win32 drive-relative paths.");
|
|
9268
|
+
}
|
|
9269
|
+
const host = url.hostname && url.hostname !== "localhost" ? `//${url.hostname}` : "";
|
|
9270
|
+
return [{
|
|
9271
|
+
path: normalizePortableOpenCodePath(`${host}${pathname}`, true),
|
|
9272
|
+
caseInsensitive: true
|
|
9273
|
+
}];
|
|
9274
|
+
}
|
|
9275
|
+
if (posix2.isAbsolute(portable) || windowsAbsolute || uncAbsolute || windowsRootRelative) {
|
|
9276
|
+
const windowsPathSemantics = windowsAbsolute || uncAbsolute || windowsRootRelative;
|
|
9277
|
+
return [{
|
|
9278
|
+
path: normalizePortableOpenCodePath(portable, windowsPathSemantics),
|
|
9279
|
+
caseInsensitive: windowsPathSemantics
|
|
9280
|
+
}];
|
|
9281
|
+
}
|
|
9282
|
+
const roots = [
|
|
9283
|
+
...projectRoot ? [resolveSessionPath(projectRoot)] : [],
|
|
9284
|
+
resolveSessionPath(targetHome)
|
|
9285
|
+
];
|
|
9286
|
+
const candidates = new Map;
|
|
9287
|
+
for (const root of roots) {
|
|
9288
|
+
const portableRoot = root.replaceAll("\\", "/");
|
|
9289
|
+
const caseInsensitive = /^[A-Za-z]:\//.test(portableRoot) || portableRoot.startsWith("//");
|
|
9290
|
+
const path = normalizePortableOpenCodePath(posix2.join(portableRoot, portable));
|
|
9291
|
+
candidates.set(`${caseInsensitive ? "i" : "s"}:${path}`, { path, caseInsensitive });
|
|
9292
|
+
}
|
|
9293
|
+
return [...candidates.values()];
|
|
9294
|
+
}
|
|
9295
|
+
function decodeOpenCodePathEscapes(value) {
|
|
9296
|
+
return value.replace(/(?:%[a-fA-F0-9]{2})+/g, (encoded) => {
|
|
9297
|
+
try {
|
|
9298
|
+
return decodeURIComponent(encoded);
|
|
9299
|
+
} catch {
|
|
9300
|
+
return encoded;
|
|
9301
|
+
}
|
|
9302
|
+
});
|
|
9303
|
+
}
|
|
9304
|
+
function normalizePortableOpenCodePath(value, windowsPathSemantics = false) {
|
|
9305
|
+
const portable = value.replaceAll("\\", "/");
|
|
9306
|
+
const componentNormalized = windowsPathSemantics ? portable.split("/").map(normalizeWin32PathComponent).join("/") : portable;
|
|
9307
|
+
const normalized = posix2.normalize(componentNormalized);
|
|
9308
|
+
return normalized.startsWith("//") ? `/${normalized.replace(/^\/+/u, "")}` : normalized;
|
|
9309
|
+
}
|
|
9310
|
+
function normalizeWin32PathComponent(component) {
|
|
9311
|
+
if (!component || /^[A-Za-z]:$/.test(component))
|
|
9312
|
+
return component;
|
|
9313
|
+
const withoutTrailingSpaces = component.replace(/ +$/u, "");
|
|
9314
|
+
if (withoutTrailingSpaces === "." || withoutTrailingSpaces === "..")
|
|
9315
|
+
return withoutTrailingSpaces;
|
|
9316
|
+
return component.replace(/[ .]+$/u, "");
|
|
9141
9317
|
}
|
|
9142
9318
|
function buildAntigravityRuleFiles(targetHome, adapter, sources) {
|
|
9143
9319
|
return sources.flatMap((source, index) => {
|
|
@@ -9191,7 +9367,7 @@ function makeAntigravityRuleFile(targetHome, relativePath, content, sourceIds) {
|
|
|
9191
9367
|
}
|
|
9192
9368
|
return file;
|
|
9193
9369
|
}
|
|
9194
|
-
function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion) {
|
|
9370
|
+
function buildFiles(targetHome, adapter, profile, sources, providerConfig, providerVersion, projectRoot) {
|
|
9195
9371
|
switch (adapter.mode) {
|
|
9196
9372
|
case "native-imports":
|
|
9197
9373
|
return buildNativeImportFiles(targetHome, adapter, profile, sources, providerVersion);
|
|
@@ -9200,7 +9376,7 @@ function buildFiles(targetHome, adapter, profile, sources, providerConfig, provi
|
|
|
9200
9376
|
case "cursor-mdc":
|
|
9201
9377
|
return buildCursorRuleFiles(targetHome, adapter, sources);
|
|
9202
9378
|
case "opencode-instructions":
|
|
9203
|
-
return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig);
|
|
9379
|
+
return buildOpenCodeFiles(targetHome, adapter, profile, sources, providerConfig, projectRoot);
|
|
9204
9380
|
case "antigravity-rules":
|
|
9205
9381
|
return buildAntigravityRuleFiles(targetHome, adapter, sources);
|
|
9206
9382
|
case "provider-rules":
|
|
@@ -9229,12 +9405,13 @@ function buildAssetFiles(input, targetHome, blocked) {
|
|
|
9229
9405
|
if (!relativePath || relativePath === ".." || relativePath.startsWith("../") || isAbsolute3(relativePath)) {
|
|
9230
9406
|
throw new Error(`Asset ${item.assetKey} is outside the session snapshot root; use a project-scoped session plan for atomic application.`);
|
|
9231
9407
|
}
|
|
9408
|
+
const renderedContent = renderNativeAgentContent(content, item.nativeAgent);
|
|
9232
9409
|
return {
|
|
9233
9410
|
path,
|
|
9234
9411
|
relativePath: assertSafeRelativePath(relativePath),
|
|
9235
9412
|
role: "asset",
|
|
9236
|
-
content,
|
|
9237
|
-
sha256: sha2565(
|
|
9413
|
+
content: renderedContent,
|
|
9414
|
+
sha256: sha2565(renderedContent),
|
|
9238
9415
|
sourceIds: [item.sourceConfigId, item.assetId]
|
|
9239
9416
|
};
|
|
9240
9417
|
});
|
|
@@ -9413,7 +9590,7 @@ function resolveSessionTargetOwnership(input, target) {
|
|
|
9413
9590
|
tool: input.tool,
|
|
9414
9591
|
profile: input.profile,
|
|
9415
9592
|
targetHome: target.targetHome,
|
|
9416
|
-
projectRoot: null,
|
|
9593
|
+
projectRoot: input.tool === "opencode" && input.projectRoot ? resolveSessionPath(input.projectRoot) : null,
|
|
9417
9594
|
ownedBy: "open-configs",
|
|
9418
9595
|
canonicalOwner: "instructions",
|
|
9419
9596
|
writer: {
|
|
@@ -9474,7 +9651,7 @@ function planSessionRender(input) {
|
|
|
9474
9651
|
if (input.providerConfig && input.tool !== "opencode") {
|
|
9475
9652
|
throw new Error("Provider base config is supported only for OpenCode session renders.");
|
|
9476
9653
|
}
|
|
9477
|
-
const baseFiles = blocked ? [] : buildFiles(targetHome, adapter, input.profile, orderedSources, input.providerConfig, input.provider_version);
|
|
9654
|
+
const baseFiles = blocked ? [] : buildFiles(targetHome, adapter, input.profile, orderedSources, input.providerConfig, input.provider_version, input.projectRoot);
|
|
9478
9655
|
const projectContext = blocked ? null : composeProjectContextSessionRender({
|
|
9479
9656
|
tool: input.tool,
|
|
9480
9657
|
adapter_mode: adapter.mode,
|
|
@@ -9575,6 +9752,7 @@ function planSessionRender(input) {
|
|
|
9575
9752
|
mutationMode: item.mutationMode,
|
|
9576
9753
|
destination: item.destination,
|
|
9577
9754
|
digest: item.source.digest,
|
|
9755
|
+
...item.nativeAgent ? { nativeAgent: item.nativeAgent } : {},
|
|
9578
9756
|
exactOnceKey: item.exactOnceKey
|
|
9579
9757
|
}))
|
|
9580
9758
|
}
|
|
@@ -11911,7 +12089,7 @@ function formatCliError(err, env = process.env) {
|
|
|
11911
12089
|
var localStoreModulePromise = null;
|
|
11912
12090
|
function localStoreModule() {
|
|
11913
12091
|
if (!localStoreModulePromise)
|
|
11914
|
-
localStoreModulePromise = import("./local-
|
|
12092
|
+
localStoreModulePromise = import("./local-jqfx3kbq.js");
|
|
11915
12093
|
return localStoreModulePromise;
|
|
11916
12094
|
}
|
|
11917
12095
|
|
|
@@ -12723,7 +12901,7 @@ function detectMachineContext(overrides = {}) {
|
|
|
12723
12901
|
created_at: "",
|
|
12724
12902
|
os_family: osFamily,
|
|
12725
12903
|
home_dir: homeDir4,
|
|
12726
|
-
workspace_root: overrides.workspace_root ??
|
|
12904
|
+
workspace_root: overrides.workspace_root ?? "",
|
|
12727
12905
|
bun_bin_dir: bunBinDir,
|
|
12728
12906
|
bun_path: overrides.bun_path ?? defaultBunPath,
|
|
12729
12907
|
path_prefix: overrides.path_prefix ?? (osFamily === "macos" ? `${join7("/opt", "homebrew", "bin")}:${bunBinDir}` : bunBinDir)
|
|
@@ -12736,7 +12914,7 @@ function machineContextToVariables(machine) {
|
|
|
12736
12914
|
OS_FAMILY: machine.os_family,
|
|
12737
12915
|
ARCH: machine.arch ?? "",
|
|
12738
12916
|
HOME_DIR: machine.home_dir,
|
|
12739
|
-
WORKSPACE_ROOT: machine.workspace_root,
|
|
12917
|
+
...machine.workspace_root ? { WORKSPACE_ROOT: machine.workspace_root } : {},
|
|
12740
12918
|
BUN_BIN_DIR: machine.bun_bin_dir,
|
|
12741
12919
|
BUN_PATH: machine.bun_path,
|
|
12742
12920
|
PATH_PREFIX: machine.path_prefix
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
expandPath,
|
|
6
6
|
getConfigHome,
|
|
7
7
|
normalizeTargetPath
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-src5t3my.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-16j8x10s.js";
|
|
17
17
|
import {
|
|
18
18
|
isSecretVarName,
|
|
19
19
|
redactContent,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
expandPath,
|
|
6
6
|
getConfigHome,
|
|
7
7
|
normalizeTargetPath
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-x0v4m19f.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-6qfy0542.js";
|
|
20
20
|
|
|
21
21
|
// src/lib/sync.ts
|
|
22
22
|
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
syncProject,
|
|
13
13
|
syncToDir,
|
|
14
14
|
syncToDisk
|
|
15
|
-
} from "./index-
|
|
16
|
-
import"./index-
|
|
17
|
-
import"./index-
|
|
15
|
+
} from "./index-ysnp8y58.js";
|
|
16
|
+
import"./index-x0v4m19f.js";
|
|
17
|
+
import"./index-6qfy0542.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-
|
|
16
|
-
import"./index-
|
|
17
|
-
import"./index-
|
|
15
|
+
} from "./index-rvb4znxa.js";
|
|
16
|
+
import"./index-src5t3my.js";
|
|
17
|
+
import"./index-16j8x10s.js";
|
|
18
18
|
import"./index-35z65jsa.js";
|
|
19
19
|
import"./index-27az1qb1.js";
|
|
20
20
|
import"./index-nnwp92tk.js";
|