@hasna/instructions 0.7.1 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -7
- package/dist/chunks/{apply-c3sd4agz.js → apply-1gyr8r0x.js} +3 -3
- package/dist/chunks/{apply-pnn7a3y7.js → apply-fyfzqc7s.js} +3 -3
- package/dist/chunks/{index-3djthcm6.js → index-27az1qb1.js} +28 -1
- package/dist/chunks/{index-r7nfef2g.js → index-6sbmg1vc.js} +3 -3
- package/dist/chunks/{index-pdpg8a44.js → index-axs3yftz.js} +2 -2
- package/dist/chunks/{index-aj66f6xr.js → index-dwagz53p.js} +92 -8
- package/dist/chunks/{index-6jncnnw7.js → index-enh4yv85.js} +274 -31
- package/dist/chunks/{index-ypcef3a2.js → index-n9arv47w.js} +2 -2
- package/dist/chunks/{index-n3fjspr0.js → index-preyvj8n.js} +28 -1
- package/dist/chunks/{index-jg8ptcwh.js → index-z27xp7fh.js} +2 -2
- package/dist/chunks/{local-0a9gja58.js → local-5dsm856v.js} +15 -4
- package/dist/chunks/{local-969ye538.js → local-yxsbs8x3.js} +15 -4
- package/dist/chunks/{sync-xtkbm5br.js → sync-6r1v8hd3.js} +4 -4
- package/dist/chunks/{sync-q5hvwq6e.js → sync-k3pab4s6.js} +4 -4
- package/dist/chunks/{template-wgnzdn7h.js → template-e4qrxs8p.js} +1 -1
- package/dist/chunks/{template-fsfxpe4p.js → template-nhn124zd.js} +1 -1
- package/dist/cli/index.js +1018 -584
- package/dist/data/config-store.d.ts +12 -4
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/db/configs.d.ts.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1264 -601
- package/dist/lib/asset-plan.d.ts +4 -1
- package/dist/lib/asset-plan.d.ts.map +1 -1
- package/dist/lib/codewith-shared-todos-storage-standard.d.ts.map +1 -1
- package/dist/lib/dangerous-operation-guard-standard.d.ts.map +1 -1
- package/dist/lib/global-agent-rules-standard.d.ts.map +1 -1
- package/dist/lib/global-source-coverage.d.ts +12 -7
- package/dist/lib/global-source-coverage.d.ts.map +1 -1
- package/dist/lib/harness-discovery.d.ts +52 -0
- package/dist/lib/harness-discovery.d.ts.map +1 -0
- package/dist/lib/instruction-graph.d.ts +1 -1
- package/dist/lib/instruction-graph.d.ts.map +1 -1
- package/dist/lib/instruction-source-policy.d.ts +6 -0
- package/dist/lib/instruction-source-policy.d.ts.map +1 -0
- package/dist/lib/machine.d.ts.map +1 -1
- package/dist/lib/managed-skill-runtimes.d.ts +12 -28
- package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
- package/dist/lib/platform-profiles.d.ts.map +1 -1
- package/dist/lib/project-dashboard-standard.d.ts.map +1 -1
- package/dist/lib/session-apply.d.ts +35 -0
- package/dist/lib/session-apply.d.ts.map +1 -1
- package/dist/lib/session-refresh.d.ts +30 -0
- package/dist/lib/session-refresh.d.ts.map +1 -0
- package/dist/lib/session-render.d.ts +41 -1
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/lib/transforms.d.ts +1 -0
- package/dist/lib/transforms.d.ts.map +1 -1
- package/dist/mcp/index.js +13 -12
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +172 -0
- package/dist/sdk/v1-client.d.ts +7 -1
- package/dist/sdk/v1-client.d.ts.map +1 -1
- package/dist/sdk/v1.generated.d.ts +26 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +199 -8
- package/dist/server/openapi.d.ts +150 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/cloud-store.d.ts.map +1 -1
- package/dist/types/index.d.ts +24 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
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
|
|
542
|
-
- `macos-arm64` for
|
|
579
|
+
- `linux-arm64` for Linux arm64
|
|
580
|
+
- `macos-arm64` for macOS arm64
|
|
543
581
|
|
|
544
|
-
|
|
545
|
-
`{{BUN_BIN_DIR}}`, `{{BUN_PATH}}`, and
|
|
546
|
-
|
|
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-
|
|
12
|
-
import"./index-
|
|
11
|
+
} from "./index-n9arv47w.js";
|
|
12
|
+
import"./index-dwagz53p.js";
|
|
13
13
|
import"./index-35z65jsa.js";
|
|
14
|
-
import"./index-
|
|
14
|
+
import"./index-27az1qb1.js";
|
|
15
15
|
import"./index-nnwp92tk.js";
|
|
16
16
|
export {
|
|
17
17
|
previewConfigs,
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
getConfigHome,
|
|
9
9
|
normalizeTargetPath,
|
|
10
10
|
previewConfigs
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-
|
|
11
|
+
} from "./index-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-
|
|
21
|
+
} from "./index-enh4yv85.js";
|
|
22
22
|
import {
|
|
23
23
|
ConfigApplyError,
|
|
24
24
|
parseTemplateVars
|
|
25
|
-
} from "./index-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
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 ??
|
|
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
|