@stalfh233/omc-cli 0.0.0-stage → 0.4.10
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/LICENSE +21 -0
- package/README.md +293 -3
- package/coverage/m1-coverage-manifest-v1.json +1278 -0
- package/dist/approval-token.js +102 -0
- package/dist/args.js +25 -0
- package/dist/artifacts.js +119 -0
- package/dist/bench/call-face-eval.js +256 -0
- package/dist/bench/context-attribution.js +151 -0
- package/dist/bench/discovery-cost-eval.js +230 -0
- package/dist/bench/driver.js +81 -0
- package/dist/bench/evals.js +236 -0
- package/dist/bench/fake-http-server.js +65 -0
- package/dist/bench/instrument.js +87 -0
- package/dist/bench/intent-face-eval.js +343 -0
- package/dist/bench/run.js +166 -0
- package/dist/bench/scenario.js +343 -0
- package/dist/bench/types.js +76 -0
- package/dist/bi-wire.js +41 -0
- package/dist/bizservice-config.js +581 -0
- package/dist/call.js +153 -0
- package/dist/capability-absences.js +23 -0
- package/dist/capability-overview.js +492 -0
- package/dist/capability-shape.js +154 -0
- package/dist/cli-contract.js +70 -0
- package/dist/cli-output.js +73 -0
- package/dist/cli.js +1418 -0
- package/dist/code-rules.js +69 -0
- package/dist/command-transport.js +155 -0
- package/dist/config-store.js +195 -0
- package/dist/context.js +21 -0
- package/dist/contract-consistency.js +66 -0
- package/dist/contract-resources.js +62 -0
- package/dist/coverage-consistency.js +62 -0
- package/dist/coverage-registry.js +76 -0
- package/dist/coverage.js +130 -0
- package/dist/data-list-filter.js +114 -0
- package/dist/discovery.js +390 -0
- package/dist/endpoints.js +154 -0
- package/dist/environment-policy.js +26 -0
- package/dist/execution-metadata.js +1092 -0
- package/dist/fake/app.js +45 -0
- package/dist/fake/b2-registration.js +594 -0
- package/dist/fake/businessrule.js +242 -0
- package/dist/fake/datarule.js +72 -0
- package/dist/fake/dictionary.js +108 -0
- package/dist/fake/environment.js +30 -0
- package/dist/fake/field.js +167 -0
- package/dist/fake/form.js +101 -0
- package/dist/fake/index.js +121 -0
- package/dist/fake/list-view.js +289 -0
- package/dist/fake/model.js +136 -0
- package/dist/fake/online-js.js +18 -0
- package/dist/fake/report.js +253 -0
- package/dist/fake/routes.js +47 -0
- package/dist/fake/rule-lifecycle.js +37 -0
- package/dist/fake/runtime-data.js +367 -0
- package/dist/fake/state.js +67 -0
- package/dist/fake/workflow.js +364 -0
- package/dist/field-change.js +200 -0
- package/dist/field-families.js +896 -0
- package/dist/form-layout.js +111 -0
- package/dist/form-support.js +821 -0
- package/dist/goal-routes.js +468 -0
- package/dist/governed-execution.js +87 -0
- package/dist/human-summary.js +212 -0
- package/dist/identity.js +62 -0
- package/dist/intent/baseline.js +57 -0
- package/dist/intent/capabilities/bizservice.js +274 -0
- package/dist/intent/capabilities/businessrule.js +493 -0
- package/dist/intent/capabilities/datarule.js +187 -0
- package/dist/intent/capabilities/field.js +545 -0
- package/dist/intent/capabilities/form.js +136 -0
- package/dist/intent/capabilities/index.js +64 -0
- package/dist/intent/capabilities/listview.js +157 -0
- package/dist/intent/capabilities/model.js +100 -0
- package/dist/intent/capabilities/onlinejs.js +108 -0
- package/dist/intent/capabilities/report.js +355 -0
- package/dist/intent/capabilities/workflow.js +458 -0
- package/dist/intent/capability.js +6 -0
- package/dist/intent/cli.js +91 -0
- package/dist/intent/compare.js +56 -0
- package/dist/intent/compiler.js +79 -0
- package/dist/intent/dsl.js +129 -0
- package/dist/intent/plan-file.js +63 -0
- package/dist/intent/readback.js +65 -0
- package/dist/intent/schema.js +158 -0
- package/dist/intent/validation.js +30 -0
- package/dist/intent/yaml.js +315 -0
- package/dist/json-column.js +68 -0
- package/dist/lanes/app-contract.js +95 -0
- package/dist/lanes/app-coverage.js +16 -0
- package/dist/lanes/app.js +174 -0
- package/dist/lanes/apply-changes.js +231 -0
- package/dist/lanes/b2-registration-contract.js +292 -0
- package/dist/lanes/b2-registration-coverage.js +48 -0
- package/dist/lanes/b2-registration.js +1187 -0
- package/dist/lanes/businessrule-contract.js +232 -0
- package/dist/lanes/businessrule-coverage.js +16 -0
- package/dist/lanes/businessrule.js +221 -0
- package/dist/lanes/contract-support.js +65 -0
- package/dist/lanes/coverage-declaration.js +9 -0
- package/dist/lanes/datarule-contract.js +155 -0
- package/dist/lanes/datarule-coverage.js +19 -0
- package/dist/lanes/datarule-protocol.js +308 -0
- package/dist/lanes/datarule.js +818 -0
- package/dist/lanes/dictionary-contract.js +78 -0
- package/dist/lanes/dictionary-coverage.js +24 -0
- package/dist/lanes/dictionary.js +235 -0
- package/dist/lanes/environment-contract.js +70 -0
- package/dist/lanes/environment-coverage.js +14 -0
- package/dist/lanes/environment.js +163 -0
- package/dist/lanes/field-contract.js +223 -0
- package/dist/lanes/field-coverage.js +27 -0
- package/dist/lanes/field.js +374 -0
- package/dist/lanes/form-contract.js +97 -0
- package/dist/lanes/form-coverage.js +16 -0
- package/dist/lanes/form.js +185 -0
- package/dist/lanes/lane-ids.js +34 -0
- package/dist/lanes/list-view-contract.js +175 -0
- package/dist/lanes/list-view-coverage.js +20 -0
- package/dist/lanes/list-view-shapes.js +1207 -0
- package/dist/lanes/list-view.js +578 -0
- package/dist/lanes/meta-contract.js +85 -0
- package/dist/lanes/meta.js +255 -0
- package/dist/lanes/model-contract.js +168 -0
- package/dist/lanes/model-coverage.js +20 -0
- package/dist/lanes/model.js +986 -0
- package/dist/lanes/online-js-contract.js +99 -0
- package/dist/lanes/online-js-coverage.js +28 -0
- package/dist/lanes/online-js.js +127 -0
- package/dist/lanes/report-contract.js +144 -0
- package/dist/lanes/report-coverage.js +21 -0
- package/dist/lanes/report.js +476 -0
- package/dist/lanes/rule-graph.js +1846 -0
- package/dist/lanes/rule-lifecycle-contract.js +92 -0
- package/dist/lanes/rule-lifecycle-coverage.js +20 -0
- package/dist/lanes/rule-lifecycle.js +176 -0
- package/dist/lanes/runtime-data-contract.js +264 -0
- package/dist/lanes/runtime-data-coverage.js +25 -0
- package/dist/lanes/runtime-data.js +1054 -0
- package/dist/lanes/workflow-contract.js +223 -0
- package/dist/lanes/workflow-coverage.js +40 -0
- package/dist/lanes/workflow.js +1813 -0
- package/dist/online-js-layout.js +58 -0
- package/dist/online-js-source.js +276 -0
- package/dist/package-tool.js +51 -0
- package/dist/package.js +73 -0
- package/dist/plan.js +73 -0
- package/dist/read.js +144 -0
- package/dist/redact.js +28 -0
- package/dist/rule-support.js +587 -0
- package/dist/runtime-support.js +134 -0
- package/dist/server.js +92 -0
- package/dist/session-manager.js +30 -0
- package/dist/session.js +149 -0
- package/dist/skills.js +112 -0
- package/dist/support.js +98 -0
- package/dist/tool-types.js +127 -0
- package/dist/tools.js +59 -0
- package/dist/usage-log.js +197 -0
- package/dist/wire.js +287 -0
- package/dist/workflow-support.js +99 -0
- package/dist/write-lease.js +26 -0
- package/dist/write-lock.js +109 -0
- package/dist/write.js +176 -0
- package/dist/zip.js +156 -0
- package/docs/tool-surface-map.md +42 -0
- package/package.json +71 -6
- package/skills/omc-acceptance-criteria.md +47 -0
- package/skills/omc-business-configuration.md +257 -0
- package/skills/omc-capabilities.md +197 -0
- package/skills/omc-capability-scouting.md +55 -0
- package/skills/omc-config-draft-review.md +171 -0
- package/skills/omc-five-piece-flow.md +35 -0
- package/skills/omc-glossary.md +86 -0
- package/skills/omc-refusals.md +110 -0
- package/skills/omc-requirement-analysis.md +161 -0
- package/skills/omc-requirement-vocabulary.md +51 -0
- package/skills/omc-start-here.md +82 -0
- package/skills/omc-tool-selection.md +119 -0
- package/skills/omc-write-hazards.md +87 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { LANE_CONTRACTS } from "./contract-resources.js";
|
|
4
|
+
import { intentCapabilityBlock } from "./intent/cli.js";
|
|
5
|
+
import { listSkills } from "./skills.js";
|
|
6
|
+
import { capabilityRouteForTool, capabilityRouteForLane, capabilityRouteIndex, DISCOVERY_AUTHORITY } from "./capability-overview.js";
|
|
7
|
+
/**
|
|
8
|
+
* `commands --json` — the tool catalogue.
|
|
9
|
+
*
|
|
10
|
+
* Round 13 slimmed it. It used to inline `discovery` (the full 14-capability
|
|
11
|
+
* route projection, ~11.4 KB, byte-identical to `omc capabilities`), and every
|
|
12
|
+
* tool row repeated `writeGate` (7.5 KB), `timeout` (7.7 KB), and a full
|
|
13
|
+
* `capability` object (10.5 KB) whose `nickname` == `id` and whose `lane` is
|
|
14
|
+
* already the row's own lane. That was ~37 KB of repetition in a 56 KB payload
|
|
15
|
+
* read once and re-sent every later turn. The route projection stays one
|
|
16
|
+
* command away (`omc capabilities`), and the per-kind governance constants move
|
|
17
|
+
* to one top-level `governance` block; each row keeps the bare `capability` id
|
|
18
|
+
* so `--compact --filter/--lane` still matches capabilities.
|
|
19
|
+
*
|
|
20
|
+
* `--compact` (round 3) drops the catalogue prose blocks and per-tool example
|
|
21
|
+
* args, leaving a bounded `purpose` line per tool.
|
|
22
|
+
*/
|
|
23
|
+
export function commandInventory(registry, options = {}) {
|
|
24
|
+
const routeByLane = capabilityRouteIndex(registry).routeByLane;
|
|
25
|
+
// One row shape for both modes (round 13). Recipe ids stay on every row: they
|
|
26
|
+
// let the agent run `describe <tool> --example <id>` (~1–2 KB) instead of
|
|
27
|
+
// `--full` (16 KB). The row no longer repeats `writeGate`/`timeout` (per-kind
|
|
28
|
+
// constants, in the top-level `governance` block) or a full `capability`
|
|
29
|
+
// object (the bare id; `nickname` == `id`, `lane` == the row's own lane,
|
|
30
|
+
// aliases come from `omc capabilities`).
|
|
31
|
+
const rows = registry.map((tool) => {
|
|
32
|
+
const capability = typeof tool.lane === "string" ? routeByLane.get(tool.lane) : undefined;
|
|
33
|
+
const recipes = (tool.executionMetadata?.recipes ?? []).map((recipe) => recipe.id);
|
|
34
|
+
return {
|
|
35
|
+
name: tool.name,
|
|
36
|
+
lane: tool.lane ?? null,
|
|
37
|
+
kind: tool.kind,
|
|
38
|
+
requiredArgs: requiredArgs(tool),
|
|
39
|
+
...(capability ? { capability: capability.id } : {}),
|
|
40
|
+
...(recipes.length > 0 ? { recipes } : {}),
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
if (options.compact === true) {
|
|
44
|
+
// The machine inventory: rows only, no catalogue prose. `--compact` used to
|
|
45
|
+
// trade boilerplate for a bounded `purpose` line; with the rows slimmed
|
|
46
|
+
// (round 13) the prose is the only difference left, so a compact query is
|
|
47
|
+
// now a strict subset of the full catalogue.
|
|
48
|
+
return {
|
|
49
|
+
discovery: { authoritative: DISCOVERY_AUTHORITY.authoritative, route: DISCOVERY_AUTHORITY.route },
|
|
50
|
+
tools: rows,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
// The authoritative route, identical to `omc help` / `omc capabilities`
|
|
55
|
+
// (ticket-07 pins the four-surface agreement). The heavy part that used to
|
|
56
|
+
// live here was the 11.4 KB capability projection, byte-identical to `omc
|
|
57
|
+
// capabilities`; that is now named, not copied.
|
|
58
|
+
discovery: { ...DISCOVERY_AUTHORITY },
|
|
59
|
+
// Per-kind constants, stated once (round 13). `kind` on each row is the
|
|
60
|
+
// discriminator; the write gate applies only to `kind:"write"`.
|
|
61
|
+
governance: {
|
|
62
|
+
writeGate: {
|
|
63
|
+
write: "environment writable permission; production needs confirmProduction",
|
|
64
|
+
read: "none",
|
|
65
|
+
governance: "none",
|
|
66
|
+
meta: "none",
|
|
67
|
+
},
|
|
68
|
+
timeout: { behavior: "bounded per call with --timeout-ms; timeout returns uncertain" },
|
|
69
|
+
},
|
|
70
|
+
tools: rows,
|
|
71
|
+
// Ticket 122 (Spec 107): the methodology layer — reachable via `omc help
|
|
72
|
+
// <topic>`, which lists this same inventory.
|
|
73
|
+
skills: listSkills(),
|
|
74
|
+
// Ticket 117 (Spec 107): the declarative usage face — agents discover the
|
|
75
|
+
// intent layer (families, lifecycle, constraints) here, wire details stay
|
|
76
|
+
// in the per-tool entries.
|
|
77
|
+
intent: intentCapabilityBlock(),
|
|
78
|
+
// Ticket 125: the Configuration capability overview lives one command away;
|
|
79
|
+
// this is only a pointer so `commands --json` stays a tool catalogue.
|
|
80
|
+
capabilities: {
|
|
81
|
+
command: "omc capabilities",
|
|
82
|
+
detail: "omc capability <id>",
|
|
83
|
+
note: "capability / order / declarative-coverage overview; not inlined here",
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Bare `omc commands` (no `--json`, no `--compact`, no scope): a bounded INDEX,
|
|
89
|
+
* not the 54 KB catalogue.
|
|
90
|
+
*
|
|
91
|
+
* Round 9 heavy-task measurement (sandbox 38): an agent exploring cold ran bare
|
|
92
|
+
* `commands` 4× at ~54 KB each — ~216 KB, 28% of the whole task — even though
|
|
93
|
+
* the full rows are the fallback face and `next`/`--compact --lane` exist. The
|
|
94
|
+
* bytes were paid before any hint could be read. So the DEFAULT face is now the
|
|
95
|
+
* lean index (name/lane/kind + lane counts + how to expand); the full rows
|
|
96
|
+
* require the documented machine entry `commands --json`, and one capability is
|
|
97
|
+
* `commands --json --compact --lane <lane>`.
|
|
98
|
+
*/
|
|
99
|
+
export function commandIndex(registry) {
|
|
100
|
+
const byLane = new Map();
|
|
101
|
+
for (const tool of registry) {
|
|
102
|
+
const lane = tool.lane ?? "(unbound)";
|
|
103
|
+
byLane.set(lane, (byLane.get(lane) ?? 0) + 1);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
discovery: { authoritative: DISCOVERY_AUTHORITY.authoritative, route: DISCOVERY_AUTHORITY.route },
|
|
107
|
+
toolCount: registry.length,
|
|
108
|
+
lanes: [...byLane.entries()].map(([lane, tools]) => ({ lane, tools })).sort((left, right) => left.lane.localeCompare(right.lane)),
|
|
109
|
+
tools: registry.map((tool) => ({ name: tool.name, lane: tool.lane ?? null, kind: tool.kind })),
|
|
110
|
+
hint: "裸 `commands` 是有界索引(name/lane/kind)。全量行用 `omc commands --json`;单能力用 `omc commands --json --compact --lane <lane>`;关键词用 `--filter <word>`;目标→路线优先 `omc next \"<目标>\"`。",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const convertToJsonSchema = zodToJsonSchema;
|
|
114
|
+
function jsonSchemaFor(shape) {
|
|
115
|
+
const objectSchema = z.object(shape);
|
|
116
|
+
return convertToJsonSchema(objectSchema, { target: "jsonSchema7", $refStrategy: "none" });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Context-cost projection: the default `describe` must stay small. A tool
|
|
120
|
+
* contract used to be 14–20 KB (`inputSchema` alone was >50%), and an agent
|
|
121
|
+
* reading it 19 times paid ~100k tokens for a handful of facts. The compact
|
|
122
|
+
* form answers "what can I pass, what is required, what is one runnable call"
|
|
123
|
+
* in ~1–2 KB; the full schema, recipes, and capability route live behind
|
|
124
|
+
* `describe <tool> --full` and `describe <tool> --param <name>`.
|
|
125
|
+
*/
|
|
126
|
+
/** First sentence, whitespace-collapsed and bounded — enough to pick a tool. */
|
|
127
|
+
function summarizeDescription(description) {
|
|
128
|
+
const collapsed = description.replace(/\s+/g, " ").trim();
|
|
129
|
+
const firstStop = collapsed.search(/[。.;;!!??]/);
|
|
130
|
+
const sentence = firstStop >= 0 ? collapsed.slice(0, firstStop + 1) : collapsed;
|
|
131
|
+
return sentence.length > 200 ? `${sentence.slice(0, 197)}...` : sentence;
|
|
132
|
+
}
|
|
133
|
+
/** A terse type label: `string`, `integer`, `array<string>`, `string: A|B`. */
|
|
134
|
+
function terseType(node) {
|
|
135
|
+
if (!node)
|
|
136
|
+
return "any";
|
|
137
|
+
if (Array.isArray(node.enum) && node.enum.length > 0) {
|
|
138
|
+
const values = node.enum.map((value) => String(value));
|
|
139
|
+
const label = `${node.type ?? "string"}: ${values.join("|")}`;
|
|
140
|
+
return label.length > 80 ? `${node.type ?? "string"} (enum)` : label;
|
|
141
|
+
}
|
|
142
|
+
if (node.type === "array")
|
|
143
|
+
return `array<${terseType(node.items)}>`;
|
|
144
|
+
return node.type ?? "any";
|
|
145
|
+
}
|
|
146
|
+
/** Compact params: `required` list + `param -> type`, no per-param prose. */
|
|
147
|
+
function compactParams(schema) {
|
|
148
|
+
const required = [...(schema.required ?? [])];
|
|
149
|
+
const params = {};
|
|
150
|
+
for (const [key, node] of Object.entries(schema.properties ?? {}))
|
|
151
|
+
params[key] = terseType(node);
|
|
152
|
+
return { required, params };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The example list: every recipe's id/title/status, but none of its args. This
|
|
156
|
+
* keeps the default `describe` small while still telling the agent which shapes
|
|
157
|
+
* exist; the full args come from `describe <tool> --example <id>`. A tool with
|
|
158
|
+
* no recipe says so explicitly and names the precondition rather than returning
|
|
159
|
+
* a silent `available:false`.
|
|
160
|
+
*/
|
|
161
|
+
function exampleList(tool) {
|
|
162
|
+
const recipes = tool.executionMetadata?.recipes ?? [];
|
|
163
|
+
if (recipes.length === 0) {
|
|
164
|
+
// Read/plain tools have no authored recipe because `required` + `params`
|
|
165
|
+
// already fully describe the call. Pointing them at `--full` (5–20 KB) made
|
|
166
|
+
// dogfood agents pay for it anyway (sandbox20: ~10 KB of read-tool --full
|
|
167
|
+
// calls). Name the cheap faces instead.
|
|
168
|
+
return [{ requiresPriorReadback: tool.kind === "write", reason: "no authored recipe needed: `required` + `params` above describe the call; per-param prose via --param <name>" }];
|
|
169
|
+
}
|
|
170
|
+
return recipes.map((recipe) => ({
|
|
171
|
+
id: recipe.id,
|
|
172
|
+
title: recipe.title,
|
|
173
|
+
status: recipe.status,
|
|
174
|
+
requiresPriorReadback: recipe.requiresEnvironmentDerivedIds,
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
/** Default `omc describe`: the compact contract projection. */
|
|
178
|
+
export function describeTool(registry, name) {
|
|
179
|
+
const tool = registry.find((entry) => entry.name === name);
|
|
180
|
+
if (!tool)
|
|
181
|
+
return undefined;
|
|
182
|
+
const schema = jsonSchemaFor(tool.inputSchema);
|
|
183
|
+
const { required, params } = compactParams(schema);
|
|
184
|
+
const examples = exampleList(tool);
|
|
185
|
+
const hasRecipe = (tool.executionMetadata?.recipes.length ?? 0) > 0;
|
|
186
|
+
return {
|
|
187
|
+
name: tool.name,
|
|
188
|
+
lane: tool.lane ?? null,
|
|
189
|
+
kind: tool.kind,
|
|
190
|
+
summary: summarizeDescription(tool.description),
|
|
191
|
+
required,
|
|
192
|
+
params,
|
|
193
|
+
examples,
|
|
194
|
+
// Point cold callers at the cheap runnable face BEFORE they reach for
|
|
195
|
+
// --full: a recipe is ~1–2 KB and a single --param is a few hundred bytes,
|
|
196
|
+
// while --full is 5–20 KB. Benchmark (bench13): two --full calls were 34 KB
|
|
197
|
+
// of a 133 KB task even though a matching recipe existed.
|
|
198
|
+
...(hasRecipe ? { exampleHint: `可运行参数用 --example <id>(~1–2KB);单参数用 --param <name>;仅当二者都缺形状才 --full` } : {}),
|
|
199
|
+
...(!hasRecipe ? { exampleHint: `无静态 recipe:required + params 已够常规调用;单参数说明用 --param <name>;仅当需要全部参数注释/拒绝形状才 --full(5–20KB)` } : {}),
|
|
200
|
+
// Keep the cost salient at the decision point: agents reached for --full even
|
|
201
|
+
// when --example/--param existed (sandbox22: 8 --full calls, one 19 KB).
|
|
202
|
+
full: `omc describe ${tool.name} --full(5–20KB;先试 --example/--param)`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/** `omc describe <tool> --example <id>`: one recipe in full, by id. */
|
|
206
|
+
export function describeExample(registry, name, exampleId) {
|
|
207
|
+
const tool = registry.find((entry) => entry.name === name);
|
|
208
|
+
if (!tool)
|
|
209
|
+
return undefined;
|
|
210
|
+
const recipes = tool.executionMetadata?.recipes ?? [];
|
|
211
|
+
const recipe = exampleId === undefined ? undefined : recipes.find((entry) => entry.id === exampleId);
|
|
212
|
+
if (!recipe) {
|
|
213
|
+
// No id (or an unknown one) lists the runnable ids instead of a dead end, so
|
|
214
|
+
// an agent that guessed never burns a retry (sandbox26: `--example` with no
|
|
215
|
+
// id was a hard commander error; an unknown id already listed `available`).
|
|
216
|
+
return {
|
|
217
|
+
name: tool.name,
|
|
218
|
+
...(exampleId !== undefined ? { example: exampleId } : {}),
|
|
219
|
+
found: false,
|
|
220
|
+
available: recipes.map((entry) => entry.id),
|
|
221
|
+
...(recipes[0] ? { hint: `本工具的例子 id 是 ${recipes.map((entry) => entry.id).join("、")};用 describe ${tool.name} --example ${recipes[0].id} 取可运行参数` } : {}),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
name: tool.name,
|
|
226
|
+
example: recipe.id,
|
|
227
|
+
title: recipe.title,
|
|
228
|
+
recipeStatus: recipe.status,
|
|
229
|
+
tool: recipe.tool,
|
|
230
|
+
args: recipe.args,
|
|
231
|
+
command: `omc call ${recipe.tool} --args '<json>'`,
|
|
232
|
+
preconditions: recipe.preconditions,
|
|
233
|
+
conditionalRequirements: recipe.conditionalRequirements,
|
|
234
|
+
priorToolReferences: recipe.priorToolReferences,
|
|
235
|
+
dryRun: recipe.dryRun,
|
|
236
|
+
expectedReadback: recipe.expectedReadback,
|
|
237
|
+
refusalRecovery: recipe.refusalRecovery,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/** One param's full schema and prose — the targeted replacement for reading the whole contract. */
|
|
241
|
+
export function describeParam(registry, name, param) {
|
|
242
|
+
const tool = registry.find((entry) => entry.name === name);
|
|
243
|
+
if (!tool)
|
|
244
|
+
return undefined;
|
|
245
|
+
const schema = jsonSchemaFor(tool.inputSchema);
|
|
246
|
+
const node = schema.properties?.[param];
|
|
247
|
+
if (!node) {
|
|
248
|
+
return { name: tool.name, param, found: false, available: Object.keys(schema.properties ?? {}) };
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
name: tool.name,
|
|
252
|
+
param,
|
|
253
|
+
required: (schema.required ?? []).includes(param),
|
|
254
|
+
type: terseType(node),
|
|
255
|
+
...(node.description ? { description: node.description } : {}),
|
|
256
|
+
schema: node,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* `omc describe <tool> --full`: the complete contract (schema, capability route).
|
|
261
|
+
*
|
|
262
|
+
* Round 13: `--full` used to also inline `executionMetadata` — the whole recipe
|
|
263
|
+
* set with full args, expectedReadback and refusalRecovery (7–8 KB for
|
|
264
|
+
* field.create / rule.save). That is reachable two cheaper ways already: the
|
|
265
|
+
* default `describe` lists the recipe ids, and `describe <tool> --example <id>`
|
|
266
|
+
* returns one recipe in ~1–2 KB. `commands --json` also carries the per-tool
|
|
267
|
+
* recipe ids. Bench (bench35 sandbox): a 77 k peak task spent 70 KB on four
|
|
268
|
+
* `describe --full` calls, of which the recipes were ~30 KB. `--full` now names
|
|
269
|
+
* the recipe ids (in `recipeIds`) and leaves the args to `--example`.
|
|
270
|
+
*/
|
|
271
|
+
export function describeToolFull(registry, name) {
|
|
272
|
+
const tool = registry.find((entry) => entry.name === name);
|
|
273
|
+
if (!tool)
|
|
274
|
+
return undefined;
|
|
275
|
+
const schema = jsonSchemaFor(tool.inputSchema);
|
|
276
|
+
const recipes = tool.executionMetadata?.recipes ?? [];
|
|
277
|
+
const recipe = recipes[0];
|
|
278
|
+
const capability = capabilityRouteForTool(registry, tool.name);
|
|
279
|
+
return {
|
|
280
|
+
name: tool.name,
|
|
281
|
+
lane: tool.lane ?? null,
|
|
282
|
+
kind: tool.kind,
|
|
283
|
+
description: tool.description,
|
|
284
|
+
...(capability ? { capability } : {}),
|
|
285
|
+
inputSchema: schema,
|
|
286
|
+
// Recipe ids only — the args live behind `--example <id>` (round 13). This
|
|
287
|
+
// keeps `--full` to its job (the schema + prose) instead of re-shipping the
|
|
288
|
+
// recipe set the default face and `--example` already cover.
|
|
289
|
+
...(recipes.length > 0 ? { recipeIds: recipes.map((entry) => entry.id) } : {}),
|
|
290
|
+
// --full is 5–20 KB. When the tool has runnable recipes, remind the caller
|
|
291
|
+
// (bench17 still pulled 18 KB of field.create --full and 8 KB of
|
|
292
|
+
// workflow.update --full although matching recipes existed) that the recipe
|
|
293
|
+
// is the cheaper, authoritative shape.
|
|
294
|
+
...(recipes.length > 0
|
|
295
|
+
? { recipeHint: `本工具已有可运行 recipe(${recipes.map((entry) => entry.id).join("、")});用 --example <id>(~1–2KB)取可运行参数,不要在 --full 里找` }
|
|
296
|
+
: {}),
|
|
297
|
+
example: recipe
|
|
298
|
+
? {
|
|
299
|
+
command: `omc call ${recipe.tool} --args '<json>'`,
|
|
300
|
+
tool: recipe.tool,
|
|
301
|
+
args: recipe.args,
|
|
302
|
+
recipeId: recipe.id,
|
|
303
|
+
status: recipe.status,
|
|
304
|
+
}
|
|
305
|
+
: {
|
|
306
|
+
tool: tool.name,
|
|
307
|
+
available: false,
|
|
308
|
+
reason: "no scenario-specific recipe; use inputSchema and discover prerequisites before execution",
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/** `omc describe <tool> --schema-only`: the raw JSON schema, nothing else. */
|
|
313
|
+
export function describeSchemaOnly(registry, name) {
|
|
314
|
+
const tool = registry.find((entry) => entry.name === name);
|
|
315
|
+
if (!tool)
|
|
316
|
+
return undefined;
|
|
317
|
+
return { name: tool.name, inputSchema: jsonSchemaFor(tool.inputSchema) };
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* `omc contract <lane>` — the compact default: who the lane binds, which tools
|
|
321
|
+
* it owns, and the wire structure's key outline. The full wire payload (14–23 KB)
|
|
322
|
+
* lives behind `--full`; most of the time an agent needs the tool names and the
|
|
323
|
+
* shape's top-level keys, not the nested bodies.
|
|
324
|
+
*/
|
|
325
|
+
export function describeContract(registry, lane) {
|
|
326
|
+
const contract = LANE_CONTRACTS.find((entry) => entry.lane === lane);
|
|
327
|
+
if (!contract)
|
|
328
|
+
return undefined;
|
|
329
|
+
const route = capabilityRouteForLane(registry, contract.lane);
|
|
330
|
+
return {
|
|
331
|
+
contract: {
|
|
332
|
+
lane: contract.lane,
|
|
333
|
+
family: contract.family,
|
|
334
|
+
referenceVersion: contract.referenceVersion,
|
|
335
|
+
tools: Object.keys(contract.tools),
|
|
336
|
+
wireKeys: Object.keys(contract.wire),
|
|
337
|
+
endpointKeys: Object.keys(contract.endpoints),
|
|
338
|
+
...(route ? { capability: { nickname: route.nickname, id: route.id, lane: route.lane, aliases: route.aliases } } : {}),
|
|
339
|
+
full: `omc contract ${contract.lane} --full`,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/** `omc contract <lane> --full`: the complete wire contract. */
|
|
344
|
+
export function describeContractFull(registry, lane) {
|
|
345
|
+
const contract = LANE_CONTRACTS.find((entry) => entry.lane === lane);
|
|
346
|
+
if (!contract)
|
|
347
|
+
return undefined;
|
|
348
|
+
const route = capabilityRouteForLane(registry, contract.lane);
|
|
349
|
+
const shape = {
|
|
350
|
+
lane: contract.lane,
|
|
351
|
+
family: contract.family,
|
|
352
|
+
referenceVersion: contract.referenceVersion,
|
|
353
|
+
endpoints: contract.endpoints,
|
|
354
|
+
wire: contract.wire,
|
|
355
|
+
tools: contract.tools,
|
|
356
|
+
...(route ? { capability: route } : {}),
|
|
357
|
+
};
|
|
358
|
+
return { contract: shape };
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* `omc contract <lane> --tool <name>` (round 3): one tool's authored lane
|
|
362
|
+
* contract slice. An agent that already knows the tool should not pull the
|
|
363
|
+
* whole 14–23 KB lane contract (the `tools` block alone is ~10 KB of prose).
|
|
364
|
+
* A missing tool names the available ones instead of silently returning empty.
|
|
365
|
+
*/
|
|
366
|
+
export function describeContractTool(registry, lane, toolName) {
|
|
367
|
+
const contract = LANE_CONTRACTS.find((entry) => entry.lane === lane);
|
|
368
|
+
if (!contract)
|
|
369
|
+
return undefined;
|
|
370
|
+
const tool = contract.tools[toolName];
|
|
371
|
+
if (!tool) {
|
|
372
|
+
return { contract: { lane: contract.lane, family: contract.family, referenceVersion: contract.referenceVersion, tool: toolName, found: false, available: Object.keys(contract.tools) } };
|
|
373
|
+
}
|
|
374
|
+
const route = capabilityRouteForLane(registry, contract.lane);
|
|
375
|
+
return {
|
|
376
|
+
contract: {
|
|
377
|
+
lane: contract.lane,
|
|
378
|
+
family: contract.family,
|
|
379
|
+
referenceVersion: contract.referenceVersion,
|
|
380
|
+
tool: { name: toolName, scope: tool.scope, description: tool.description },
|
|
381
|
+
...(route ? { capability: { nickname: route.nickname, id: route.id, lane: route.lane, aliases: route.aliases } } : {}),
|
|
382
|
+
full: `omc contract ${contract.lane} --full`,
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function requiredArgs(tool) {
|
|
387
|
+
const schema = jsonSchemaFor(tool.inputSchema);
|
|
388
|
+
return schema.required ?? [];
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-proven CloudPivot 8.6 wire endpoints (from the M1 coverage manifest
|
|
3
|
+
* evidence chains). Every low-level tool drives exactly these paths — no
|
|
4
|
+
* invented surfaces.
|
|
5
|
+
*/
|
|
6
|
+
export const ENDPOINTS = {
|
|
7
|
+
applicationList: "/api/api/app/apppackage/list",
|
|
8
|
+
applicationGroupList: "/api/api/app/apppackage/list_all_group",
|
|
9
|
+
applicationGet: "/api/api/app/apppackage/get",
|
|
10
|
+
applicationCreate: "/api/api/app/apppackage/create",
|
|
11
|
+
applicationUpdate: "/api/api/app/apppackage/update",
|
|
12
|
+
applicationDelete: "/api/api/app/apppackage/delete",
|
|
13
|
+
applicationTree: "/api/api/app/apppackage/trees",
|
|
14
|
+
modelList: "/api/api/app/bizmodels/list_schema",
|
|
15
|
+
modelGet: "/api/api/app/bizmodels/get_all",
|
|
16
|
+
modelCreate: "/api/api/app/bizmodels/create",
|
|
17
|
+
modelGetSummary: "/api/api/app/bizmodels/get_summary",
|
|
18
|
+
modelUpdateSummary: "/api/api/app/bizmodels/update_summary",
|
|
19
|
+
modelUpdate: "/api/api/app/bizmodels/update",
|
|
20
|
+
appPackagePhysicallyDelete: "/api/api/app/apppackage/physically_delete",
|
|
21
|
+
fieldList: "/api/api/app/bizproperty/list",
|
|
22
|
+
fieldGet: "/api/api/app/bizproperty/get",
|
|
23
|
+
fieldCreate: "/api/api/app/bizproperty/create",
|
|
24
|
+
fieldUpdate: "/api/api/app/bizproperty/update",
|
|
25
|
+
fieldPublish: "/api/api/app/bizproperty/publish",
|
|
26
|
+
fieldDelete: "/api/api/app/bizproperty/delete",
|
|
27
|
+
fieldForceDelete: "/api/api/app/bizproperty/force_delete",
|
|
28
|
+
dictionarySearch: "/api/api/data_dictionary/searchDictionary",
|
|
29
|
+
dictionaryGet: "/api/api/data_dictionary/getDictionaryById",
|
|
30
|
+
dictionaryGetByCode: "/api/api/data_dictionary/getDictionaryByCode",
|
|
31
|
+
dictionaryGetByType: "/api/api/data_dictionary/getDictionaryByType",
|
|
32
|
+
dictionaryIdAndNames: "/api/api/data_dictionary/getDictionaryIdAndNames",
|
|
33
|
+
dictionarySave: "/api/api/data_dictionary/saveDictionary",
|
|
34
|
+
dictionaryUpdateStatus: "/api/api/data_dictionary/updateDictionaryStatus",
|
|
35
|
+
dictionaryRecords: "/api/api/data_dictionary/searchDictionaryRecord",
|
|
36
|
+
dictionaryRecordsByCode: "/api/api/data_dictionary/searchDictionaryRecordByCode",
|
|
37
|
+
dictionaryEnabledRecords: "/api/api/data_dictionary/getEnableRecordsByDictionaryId",
|
|
38
|
+
dictionaryEnabledRecordsByCode: "/api/api/data_dictionary/getEnableRecordsByDictionaryCode",
|
|
39
|
+
dictionaryParentRecords: "/api/api/data_dictionary/getDictionaryRecordByParentId",
|
|
40
|
+
dictionaryRecordStatus: "/api/api/data_dictionary/updateDictionaryRecordStatus",
|
|
41
|
+
dictionaryRecordUsed: "/api/api/data_dictionary/updateDictionaryRecordUsed",
|
|
42
|
+
dictionaryClasses: "/api/api/data_dictionary/getDictionaryClass",
|
|
43
|
+
dictionaryClassDetail: "/api/api/data_dictionary/getDictionaryClassDetail",
|
|
44
|
+
dictionaryClassSave: "/api/api/data_dictionary/saveDictionaryClass",
|
|
45
|
+
dictionaryClassDelete: "/api/api/data_dictionary/deleteDictionaryClass",
|
|
46
|
+
dictionaryClassDeleteBatch: "/api/api/data_dictionary/deleteDictionaryClassBatch",
|
|
47
|
+
sheetGet: "/api/api/app/bizsheet/get",
|
|
48
|
+
sheetCreate: "/api/api/app/bizsheet/create",
|
|
49
|
+
sheetUpdate: "/api/api/app/bizsheet/update",
|
|
50
|
+
sheetPublish: "/api/api/app/bizsheet/publish",
|
|
51
|
+
sheetHistoryList: "/api/api/app/bizsheet/history/list",
|
|
52
|
+
businessRuleListBySchemaCode: "/api/api/app/businessrule/list_by_schemacode",
|
|
53
|
+
runtimeBusinessRuleListBySchemaCode: "/api/api/runtime/business_rule/list_by_schemacode",
|
|
54
|
+
businessRuleGet: "/api/api/app/businessrule/get",
|
|
55
|
+
businessRuleCreate: "/api/api/app/businessrule/create",
|
|
56
|
+
businessRuleUpdate: "/api/api/app/businessrule/update",
|
|
57
|
+
businessRulePublish: "/api/api/app/businessrule/publish",
|
|
58
|
+
businessRuleEnable: "/api/api/app/businessrule/enable",
|
|
59
|
+
businessRuleDelete: "/api/api/app/businessrule/delete",
|
|
60
|
+
dataRuleCreate: "/api/api/app/bizdatarule/create",
|
|
61
|
+
dataRuleList: "/api/api/app/bizdatarule/list",
|
|
62
|
+
dataRuleUpdate: "/api/api/app/bizdatarule/update",
|
|
63
|
+
dataRuleDelete: "/api/api/app/bizdatarule/delete",
|
|
64
|
+
runtimeFormSave: "/api/api/runtime/form/save",
|
|
65
|
+
runtimeFormLoad: "/api/api/runtime/form/load",
|
|
66
|
+
runtimeFormReplayToken: "/api/api/runtime/form/getReplayToken",
|
|
67
|
+
runtimeQueryList: "/api/api/runtime/query/list",
|
|
68
|
+
runtimeFormDelete: "/api/api/runtime/form/delete",
|
|
69
|
+
runtimeFormSubmit: "/api/api/runtime/form/submit",
|
|
70
|
+
bizServiceCreate: "/api/api/bizservice/service/create",
|
|
71
|
+
bizServiceUpdate: "/api/api/bizservice/service/update",
|
|
72
|
+
bizServiceGetByCode: "/api/api/bizservice/service/get_by_code",
|
|
73
|
+
bizServiceCategoryList: "/api/api/bizservice/category/list",
|
|
74
|
+
bizServiceCategoryCreate: "/api/api/bizservice/category/create",
|
|
75
|
+
bizServiceCategoryUpdate: "/api/api/bizservice/category/update",
|
|
76
|
+
bizServiceCategoryDelete: "/api/api/bizservice/category/delete",
|
|
77
|
+
bizDbConnPoolList: "/api/api/bizservice/dbconnpool/list",
|
|
78
|
+
bizDbConnPoolCreate: "/api/api/bizservice/dbconnpool/create",
|
|
79
|
+
bizDbConnPoolUpdate: "/api/api/bizservice/dbconnpool/update",
|
|
80
|
+
bizDbConnPoolDelete: "/api/api/bizservice/dbconnpool/delete",
|
|
81
|
+
bizServiceAdapterConfig: "/api/api/bizservice/service/adapter_config",
|
|
82
|
+
bizServiceTableList: "/api/api/bizservice/method/get_tablename_list",
|
|
83
|
+
bizServiceTableSql: "/api/api/bizservice/method/get_table_column",
|
|
84
|
+
bizServiceMethodCreate: "/api/api/bizservice/method/create",
|
|
85
|
+
bizServiceMethodUpdate: "/api/api/bizservice/method/update",
|
|
86
|
+
bizServiceMethodGet: "/api/api/bizservice/method/get",
|
|
87
|
+
bizServiceMethodDelete: "/api/api/bizservice/method/delete",
|
|
88
|
+
bizServiceMethodTest: "/api/api/bizservice/method/service_test",
|
|
89
|
+
bizServiceMethodList: "/api/api/bizservice/method/list_by_service_code",
|
|
90
|
+
bizServiceDelete: "/api/api/bizservice/service/delete",
|
|
91
|
+
bizServiceExport: "/api/api/bizservice/service/export",
|
|
92
|
+
bizServiceCheck: "/api/api/bizservice/service/check",
|
|
93
|
+
bizServiceImport: "/api/api/bizservice/service/import",
|
|
94
|
+
runtimeQueryUploadFile: "/api/api/runtime/query/upload_file",
|
|
95
|
+
// `/api/api/programming/*` (design-time 在线开发: business-rule / SPI /
|
|
96
|
+
// service-component JAVA source) is deliberately NOT wrapped. It is backend
|
|
97
|
+
// Java authored through 二开扩展包, not form Online JS, and no operator asked
|
|
98
|
+
// for it here — so the CLI exposes no tool for it. Live 2026-09-21 evidence
|
|
99
|
+
// (ProgrammingController.java:99, base is the doubled `/api/api/programming`
|
|
100
|
+
// under the `/api` context-path; the earlier single-`/api` form 404s) is
|
|
101
|
+
// recorded in the online-js contract's history note.
|
|
102
|
+
workflowCreate: "/api/api/workflow/create",
|
|
103
|
+
workflowGetHeader: "/api/api/workflow/get_header",
|
|
104
|
+
workflowGetDraft: "/api/api/workflow/get_draft",
|
|
105
|
+
workflowIsWorkflow: "/api/api/workflow/isworkflow",
|
|
106
|
+
workflowGetBySchema: "/api/api/workflow/getWorkflow",
|
|
107
|
+
workflowGetPublished: "/api/api/workflow/get_published",
|
|
108
|
+
workflowUpdate: "/api/api/workflow/update",
|
|
109
|
+
workflowValidate: "/api/api/workflow/validate",
|
|
110
|
+
workflowPublish: "/api/api/workflow/publish",
|
|
111
|
+
workflowDelete: "/api/api/workflow/delete",
|
|
112
|
+
workflowSearchWorkItems: "/api/api/runtime/workflow/search_workitems",
|
|
113
|
+
workflowGetBizObjectByWfInstanceId: "/api/api/runtime/workflow/getBizObjectByWfInstanceId",
|
|
114
|
+
organizationRoleList: "/api/api/organization/role/list",
|
|
115
|
+
organizationDepartmentTree: "/api/api/organization/department/tree",
|
|
116
|
+
organizationUserSearch: "/api/api/organization/user/search",
|
|
117
|
+
listQueryCreate: "/api/api/app/query/create",
|
|
118
|
+
listQueryGet: "/api/api/app/query/get",
|
|
119
|
+
listQueryUpdate: "/api/api/app/query/update",
|
|
120
|
+
listQueryUpdateHeader: "/api/api/app/query/update_header",
|
|
121
|
+
listQueryGetHeader: "/api/api/app/query/get_header",
|
|
122
|
+
listQueryList: "/api/api/app/query/list",
|
|
123
|
+
listQueryDelete: "/api/api/app/query/delete",
|
|
124
|
+
// R1-report — design-time report pages live on the platform channel
|
|
125
|
+
// (`/api/api/report/*`, errcode envelope); the BI chart/dashboard face lives
|
|
126
|
+
// on the separate `/dashboard/v1/*` channel (no errcode envelope; auth is a
|
|
127
|
+
// `config` object carried in the request body). Both are live-proven on the
|
|
128
|
+
// aozhe tenant (AI-Platform-v1.1.22, engineCode aozhe).
|
|
129
|
+
reportTreeAll: "/api/api/app/folders/queryReportChartTree",
|
|
130
|
+
reportTreeByApp: "/api/api/runtime/app/queryReportChartTreeByApp",
|
|
131
|
+
reportGet: "/api/api/report/get",
|
|
132
|
+
reportFrontGet: "/api/api/report/frontget",
|
|
133
|
+
reportCreate: "/api/api/report/create",
|
|
134
|
+
reportUpdate: "/api/api/report/update",
|
|
135
|
+
reportDelete: "/api/api/report/logical_delete",
|
|
136
|
+
biReportConfig: "/dashboard/v1/report/v2/config",
|
|
137
|
+
biReportPageSave: "/dashboard/v1/report/v2/reportpage",
|
|
138
|
+
biReportRemove: "/dashboard/v1/report/removeReport",
|
|
139
|
+
biReportSaveGlobal: "/dashboard/v1/report/saveGlobal",
|
|
140
|
+
biReportSaveAttributes: "/dashboard/v1/report/saveAttributes",
|
|
141
|
+
biReportGlobalFilters: "/dashboard/v1/report/local_global_filters",
|
|
142
|
+
biChartAdd: "/dashboard/v1/chart/addChart",
|
|
143
|
+
biChartUpdate: "/dashboard/v1/chart/updateChart",
|
|
144
|
+
biChartRemove: "/dashboard/v1/chart/removeChart",
|
|
145
|
+
biChartRemoveMany: "/dashboard/v1/chart/removeCharts",
|
|
146
|
+
biChartUpdateTitle: "/dashboard/v1/chart/updateTitle",
|
|
147
|
+
biChartUpdatePositions: "/dashboard/v1/chart/updatePositions",
|
|
148
|
+
biChartData: "/dashboard/v1/datalogic/v3/chartdata",
|
|
149
|
+
biDatasourceModelList: "/dashboard/v1/report/v3/datasourcelist",
|
|
150
|
+
biDatasourceModelLink: "/dashboard/v1/report/v3/datasource",
|
|
151
|
+
biDatasourceAdvancedList: "/dashboard/datasource/advanced_list",
|
|
152
|
+
biDatasourceList: "/dashboard/datasource/v2/datasource_list",
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The environment's write permission: the single machine-side write gate. */
|
|
2
|
+
export function environmentWritable(profile) {
|
|
3
|
+
return profile.writable === true;
|
|
4
|
+
}
|
|
5
|
+
export function environmentKind(profile) {
|
|
6
|
+
return profile.production === true ? "生产环境" : "测试环境";
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A production environment is a high-risk write target: writable exactly like
|
|
10
|
+
* any other, but every write must carry an explicit per-write confirmation that
|
|
11
|
+
* is recorded in the audit artifact. The mark is a risk label, not a gate.
|
|
12
|
+
*/
|
|
13
|
+
export function requiresProductionConfirmation(profile) {
|
|
14
|
+
return profile.production === true;
|
|
15
|
+
}
|
|
16
|
+
export function environmentNotice(profile) {
|
|
17
|
+
if (profile.production === true) {
|
|
18
|
+
return environmentWritable(profile)
|
|
19
|
+
? "当前是生产环境;写入前必须逐笔携带显式高危确认(confirmProduction:true),确认会记入审计工件。"
|
|
20
|
+
: "当前是生产环境;当前设置为只读,写入会被拒绝。";
|
|
21
|
+
}
|
|
22
|
+
return environmentWritable(profile)
|
|
23
|
+
? "当前是测试环境;已允许写入,仅应使用测试数据。"
|
|
24
|
+
: "当前是测试环境;当前设置为只读,写入会被拒绝。";
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=environment-policy.js.map
|