orizu 0.5.30 → 0.5.32
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/dist/app-commands.d.ts +2 -0
- package/dist/app-commands.d.ts.map +1 -1
- package/dist/app-commands.js +10 -4
- package/dist/gepa-engine-dispatch.d.ts.map +1 -1
- package/dist/gepa-engine-dispatch.js +16 -1
- package/dist/help.js +7 -7
- package/dist/hosted-agent-prompt.d.ts +14 -0
- package/dist/hosted-agent-prompt.d.ts.map +1 -0
- package/dist/hosted-agent-prompt.js +17 -0
- package/dist/hosted-gepa-cli.d.ts.map +1 -1
- package/dist/hosted-gepa-cli.js +7 -1
- package/dist/hosted-harness-claude.d.ts.map +1 -1
- package/dist/hosted-harness-claude.js +4 -1
- package/dist/hosted-harness-opencode.d.ts +1 -0
- package/dist/hosted-harness-opencode.d.ts.map +1 -1
- package/dist/hosted-harness-opencode.js +27 -7
- package/dist/hosted-harness.d.ts +30 -1
- package/dist/hosted-harness.d.ts.map +1 -1
- package/dist/hosted-harness.js +5 -0
- package/dist/hosted-optimization-prebaked-marker.d.ts +9 -0
- package/dist/hosted-optimization-prebaked-marker.d.ts.map +1 -0
- package/dist/hosted-optimization-prebaked-marker.js +22 -0
- package/dist/hosted-tool-hints.d.ts +56 -0
- package/dist/hosted-tool-hints.d.ts.map +1 -0
- package/dist/hosted-tool-hints.js +105 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/instruction-set-gepa-launch.d.ts +21 -2
- package/dist/instruction-set-gepa-launch.d.ts.map +1 -1
- package/dist/instruction-set-gepa-launch.js +123 -3
- package/dist/markdown-report-input.d.ts.map +1 -1
- package/dist/markdown-report-input.js +1 -1
- package/dist/optimizations-promote-cli.d.ts.map +1 -1
- package/dist/optimizations-promote-cli.js +19 -0
- package/dist/preview-runtime.d.ts +7 -0
- package/dist/preview-runtime.d.ts.map +1 -1
- package/dist/preview-runtime.js +49 -5
- package/dist/provider-refusals.js +2 -2
- package/dist/report-markdown-blankness.d.ts +6 -0
- package/dist/report-markdown-blankness.d.ts.map +1 -1
- package/dist/report-markdown-blankness.js +47 -4
- package/dist/seed-against-production.d.ts +11 -0
- package/dist/seed-against-production.d.ts.map +1 -0
- package/dist/seed-against-production.js +1 -0
- package/dist/setup-and-skills-commands.d.ts.map +1 -1
- package/dist/setup-and-skills-commands.js +123 -9
- package/dist/skill-installer.d.ts +32 -0
- package/dist/skill-installer.d.ts.map +1 -1
- package/dist/skill-installer.js +228 -1
- package/package.json +1 -1
- package/src/app-commands.ts +13 -3
- package/src/gepa-engine-dispatch.ts +18 -1
- package/src/help.ts +7 -7
- package/src/hosted-agent-prompt.ts +18 -0
- package/src/hosted-gepa-cli.ts +7 -1
- package/src/hosted-harness-claude.ts +4 -1
- package/src/hosted-harness-opencode.ts +28 -7
- package/src/hosted-harness.ts +32 -1
- package/src/hosted-optimization-prebaked-marker.ts +20 -0
- package/src/hosted-tool-hints.ts +153 -0
- package/src/index.ts +2 -5
- package/src/instruction-set-gepa-launch.ts +161 -3
- package/src/markdown-report-input.ts +3 -1
- package/src/optimizations-promote-cli.ts +20 -2
- package/src/preview-runtime.ts +44 -5
- package/src/provider-refusals.ts +2 -2
- package/src/report-markdown-blankness.ts +59 -4
- package/src/seed-against-production.ts +10 -0
- package/src/setup-and-skills-commands.ts +160 -8
- package/src/skill-installer.ts +315 -0
- package/vendor/skills/orizu/SKILL.md +3 -3
- package/vendor/skills/orizu/flows/first-win.md +3 -1
- package/vendor/skills/orizu/flows/promote.md +2 -1
- package/vendor/skills/orizu/references/building-apps.md +2 -0
- package/vendor/skills/orizu/references/building-judges.md +138 -8
- package/vendor/skills/orizu/references/cli-reference.md +2 -2
- package/vendor/skills/orizu/references/migrate-existing-gepa-setup.md +1 -2
- package/vendor/skills/orizu/references/optimization-reports.md +1 -1
- package/vendor/skills/orizu/references/optimization-with-gepa.md +22 -4
- package/vendor/skills/orizu/references/primer.md +2 -2
- package/vendor/skills/orizu/references/prompt-control-plane.md +6 -1
- package/vendor/skills/orizu/scripts/test-app.mjs +53 -4
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const OPENCODE = 'opencode';
|
|
2
|
+
const CLAUDE_AGENT_SDK = 'claude-agent-sdk';
|
|
3
|
+
/** What kind of thing a tool does — the renderer picks an icon/layout from
|
|
4
|
+
* this, never from the tool name. */
|
|
5
|
+
export const TOOL_CATEGORIES = {
|
|
6
|
+
file: 'file',
|
|
7
|
+
command: 'command',
|
|
8
|
+
search: 'search',
|
|
9
|
+
network: 'network',
|
|
10
|
+
question: 'question',
|
|
11
|
+
subAgent: 'sub-agent',
|
|
12
|
+
list: 'list',
|
|
13
|
+
plug: 'plug',
|
|
14
|
+
other: 'other',
|
|
15
|
+
};
|
|
16
|
+
/** How the tool's output text should be shown. */
|
|
17
|
+
export const TOOL_OUTPUT_KINDS = {
|
|
18
|
+
text: 'text',
|
|
19
|
+
diff: 'diff',
|
|
20
|
+
markdown: 'markdown',
|
|
21
|
+
json: 'json',
|
|
22
|
+
list: 'list',
|
|
23
|
+
};
|
|
24
|
+
// Argument names that look like they hold a credential. Redacted for every
|
|
25
|
+
// tool, and never used as the fallback summary.
|
|
26
|
+
const SECRET_LOOKING_KEY = /token|secret|password|passwd|api[_-]?key|authorization|credential/i;
|
|
27
|
+
/**
|
|
28
|
+
* Look a tool up in a driver's hint table. A tool the table does not know (an
|
|
29
|
+
* MCP tool, a plug-in) falls back to the `plug` category, summarized by its
|
|
30
|
+
* first non-empty string argument that does not look like a secret.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveToolHint(table, tool, args = {}) {
|
|
33
|
+
const known = Object.hasOwn(table, tool) ? table[tool] : undefined;
|
|
34
|
+
const secretKeys = Object.keys(args).filter(key => SECRET_LOOKING_KEY.test(key));
|
|
35
|
+
const redactKeys = [...new Set([...(known?.redactKeys ?? []), ...secretKeys])];
|
|
36
|
+
if (known)
|
|
37
|
+
return { ...known, redactKeys };
|
|
38
|
+
const summaryKey = Object.keys(args).find(key => {
|
|
39
|
+
const value = args[key];
|
|
40
|
+
return typeof value === 'string' && value.length > 0 && !redactKeys.includes(key);
|
|
41
|
+
}) ?? null;
|
|
42
|
+
return { category: TOOL_CATEGORIES.plug, summaryKey, outputKind: TOOL_OUTPUT_KINDS.text, redactKeys };
|
|
43
|
+
}
|
|
44
|
+
// OpenCode's built-in tools, as the pinned opencode-ai@1.14.41 tool registry
|
|
45
|
+
// lists them, with the input key that summarizes each call. Tools not listed
|
|
46
|
+
// here (MCP tools, plug-ins) resolve to `plug` through resolveToolHint.
|
|
47
|
+
export const OPENCODE_TOOL_HINTS = {
|
|
48
|
+
read: { category: 'file', label: 'Read', summaryKey: 'filePath', outputKind: 'text', redactKeys: [] },
|
|
49
|
+
edit: { category: 'file', label: 'Edited', summaryKey: 'filePath', outputKind: 'diff', redactKeys: ['oldString', 'newString'] },
|
|
50
|
+
write: { category: 'file', label: 'Wrote', summaryKey: 'filePath', outputKind: 'text', redactKeys: ['content'] },
|
|
51
|
+
apply_patch: { category: 'file', label: 'Edited', summaryKey: 'patchText', outputKind: 'diff', redactKeys: [] },
|
|
52
|
+
lsp: { category: 'file', label: 'Checked', summaryKey: 'filePath', outputKind: 'json', redactKeys: [] },
|
|
53
|
+
bash: { category: 'command', label: 'Ran', summaryKey: 'command', outputKind: 'text', redactKeys: [] },
|
|
54
|
+
glob: { category: 'search', label: 'Listed', summaryKey: 'pattern', outputKind: 'list', redactKeys: [] },
|
|
55
|
+
grep: { category: 'search', label: 'Searched', summaryKey: 'pattern', outputKind: 'text', redactKeys: [] },
|
|
56
|
+
webfetch: { category: 'network', label: 'Fetched', summaryKey: 'url', outputKind: 'markdown', redactKeys: [] },
|
|
57
|
+
websearch: { category: 'network', label: 'Searched', summaryKey: 'query', outputKind: 'text', redactKeys: [] },
|
|
58
|
+
question: { category: 'question', label: 'Asked', summaryKey: 'questions', outputKind: 'text', redactKeys: [] },
|
|
59
|
+
plan_exit: { category: 'question', label: 'Asked', summaryKey: null, outputKind: 'text', redactKeys: [] },
|
|
60
|
+
task: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
61
|
+
todowrite: { category: 'list', label: 'Planned', summaryKey: 'todos', outputKind: 'json', redactKeys: [] },
|
|
62
|
+
skill: { category: 'other', label: 'Loaded', summaryKey: 'name', outputKind: 'markdown', redactKeys: [] },
|
|
63
|
+
invalid: { category: 'other', label: 'Invalid', summaryKey: 'tool', outputKind: 'text', redactKeys: [] },
|
|
64
|
+
};
|
|
65
|
+
// The Claude Agent SDK's built-in tools (SDK 0.3.201: input types in
|
|
66
|
+
// sdk-tools.d.ts, names from the SDK; `Task` is the older name of `Agent`),
|
|
67
|
+
// with the input key that summarizes each call. MCP tools
|
|
68
|
+
// (`mcp__<server>__<tool>`) are not listed and resolve to `plug` through
|
|
69
|
+
// resolveToolHint. This driver sends no `title` or `metadata`: the SDK has no
|
|
70
|
+
// equivalent of OpenCode's.
|
|
71
|
+
export const CLAUDE_TOOL_HINTS = {
|
|
72
|
+
Read: { category: 'file', label: 'Read', summaryKey: 'file_path', outputKind: 'text', redactKeys: [] },
|
|
73
|
+
Edit: { category: 'file', label: 'Edited', summaryKey: 'file_path', outputKind: 'text', redactKeys: ['old_string', 'new_string'] },
|
|
74
|
+
Write: { category: 'file', label: 'Wrote', summaryKey: 'file_path', outputKind: 'text', redactKeys: ['content'] },
|
|
75
|
+
NotebookEdit: { category: 'file', label: 'Edited', summaryKey: 'notebook_path', outputKind: 'text', redactKeys: ['new_source'] },
|
|
76
|
+
Bash: { category: 'command', label: 'Ran', summaryKey: 'command', outputKind: 'text', redactKeys: [] },
|
|
77
|
+
TaskOutput: { category: 'command', label: 'Checked', summaryKey: 'task_id', outputKind: 'text', redactKeys: [] },
|
|
78
|
+
TaskStop: { category: 'command', label: 'Stopped', summaryKey: 'task_id', outputKind: 'text', redactKeys: [] },
|
|
79
|
+
Glob: { category: 'search', label: 'Listed', summaryKey: 'pattern', outputKind: 'list', redactKeys: [] },
|
|
80
|
+
Grep: { category: 'search', label: 'Searched', summaryKey: 'pattern', outputKind: 'text', redactKeys: [] },
|
|
81
|
+
WebFetch: { category: 'network', label: 'Fetched', summaryKey: 'url', outputKind: 'markdown', redactKeys: [] },
|
|
82
|
+
WebSearch: { category: 'network', label: 'Searched', summaryKey: 'query', outputKind: 'text', redactKeys: [] },
|
|
83
|
+
AskUserQuestion: { category: 'question', label: 'Asked', summaryKey: 'questions', outputKind: 'text', redactKeys: [] },
|
|
84
|
+
ExitPlanMode: { category: 'question', label: 'Asked', summaryKey: null, outputKind: 'markdown', redactKeys: [] },
|
|
85
|
+
Agent: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
86
|
+
Task: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
87
|
+
TodoWrite: { category: 'list', label: 'Planned', summaryKey: 'todos', outputKind: 'text', redactKeys: [] },
|
|
88
|
+
ListMcpResourcesTool: { category: 'plug', label: 'Listed', summaryKey: 'server', outputKind: 'json', redactKeys: [] },
|
|
89
|
+
ReadMcpResourceTool: { category: 'plug', label: 'Read', summaryKey: 'uri', outputKind: 'text', redactKeys: [] },
|
|
90
|
+
Skill: { category: 'other', label: 'Loaded', summaryKey: 'skill', outputKind: 'markdown', redactKeys: [] },
|
|
91
|
+
};
|
|
92
|
+
const NO_HINTS = {};
|
|
93
|
+
/**
|
|
94
|
+
* The hint table for the harness that produced an event. Events recorded
|
|
95
|
+
* before the seam named its harness came from OpenCode, the default driver.
|
|
96
|
+
* A harness with no table here (a future pi driver, say) gets none, so every
|
|
97
|
+
* tool falls back to its own name and first string argument.
|
|
98
|
+
*/
|
|
99
|
+
export function toolHintsFor(harness) {
|
|
100
|
+
if (harness === undefined || harness === OPENCODE)
|
|
101
|
+
return OPENCODE_TOOL_HINTS;
|
|
102
|
+
if (harness === CLAUDE_AGENT_SDK)
|
|
103
|
+
return CLAUDE_TOOL_HINTS;
|
|
104
|
+
return NO_HINTS;
|
|
105
|
+
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsLA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsLA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AA4tCtD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B1G;AAED,eAAO,MAAM,iBAAiB,SAAU,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAkB,CAAA;AACtD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAexH;AAmMD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBAyhBzD;AA6DD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAEhF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { resolveAuthTokenForBaseUrl } from './credentials.js';
|
|
|
31
31
|
import { applyHostedInstructionSetProfileOverride, dispatchHostedCommands } from './hosted-commands.js';
|
|
32
32
|
import { dispatchGepaEngine } from './gepa-engine-dispatch.js';
|
|
33
33
|
import { getGepaPythonPathEntries } from './gepa-python-paths.js';
|
|
34
|
-
import {
|
|
34
|
+
import { resolveGepaSeedFromEnvironment } from './instruction-set-gepa-launch.js';
|
|
35
35
|
import { prepareSkilledProposerLaunch, spawnSkilledProposerChild } from './skilled-proposer-launch.js';
|
|
36
36
|
import { reportCommentsCommand, throwDeprecatedPromptCommentsCommand } from './report-comments-cli.js';
|
|
37
37
|
import { getCapabilities, renderHelpForArgs } from './help.js';
|
|
@@ -997,10 +997,7 @@ async function runGepaOptimization() {
|
|
|
997
997
|
PYTHONPATH: getGepaPythonPathEntries(process.env.PYTHONPATH).join(delimiter),
|
|
998
998
|
PYTHONUNBUFFERED: process.env.PYTHONUNBUFFERED || '1',
|
|
999
999
|
}));
|
|
1000
|
-
const
|
|
1001
|
-
const modelConfigIdentity = dispatch.environment.ORIZU_MODEL_CONFIG_IDENTITY;
|
|
1002
|
-
const instructionSetProfileVersionId = instructionSetName && modelConfigIdentity
|
|
1003
|
-
? await resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project) : undefined;
|
|
1000
|
+
const instructionSetProfileVersionId = await resolveGepaSeedFromEnvironment(dispatch.environment, project, 'production');
|
|
1004
1001
|
if (instructionSetProfileVersionId)
|
|
1005
1002
|
dispatch.environment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_ID = instructionSetProfileVersionId;
|
|
1006
1003
|
selectedEngine = dispatch.engine;
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
1
|
+
/** The Seed a run-gepa launch names: set reference, profile, and optional version. */
|
|
2
|
+
export interface GepaSeedSelector {
|
|
3
|
+
instructionSetName: string;
|
|
4
|
+
modelConfigIdentity?: string;
|
|
5
|
+
versionNumber?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Combine `--instruction-set`, `--model-config` and `--profile-version` into
|
|
9
|
+
* one Seed. A value with `/` or `@` is a specifier (`set/profile@vN`); any
|
|
10
|
+
* other value is a set slug or exact name, passed through unchanged. Values
|
|
11
|
+
* named twice must agree, the same rule `sync` applies to `--version`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function gepaSeedSelector(instructionSetArg: string, modelConfigFlag: string | undefined, versionFlag: string | undefined): GepaSeedSelector;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the Seed that dispatch normalised into the connector environment.
|
|
16
|
+
* Returns undefined when no instruction set was selected. When no version is
|
|
17
|
+
* named, `unversioned: 'production'` resolves the profile's Production here
|
|
18
|
+
* (local runs); `unversioned: 'server'` leaves it to the hosted launch route,
|
|
19
|
+
* which resolves Production itself in the same call that queues the run.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveGepaSeedFromEnvironment(environment: NodeJS.ProcessEnv, project: string, unversioned: 'production' | 'server'): Promise<string | undefined>;
|
|
3
22
|
//# sourceMappingURL=instruction-set-gepa-launch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instruction-set-gepa-launch.d.ts","sourceRoot":"","sources":["../src/instruction-set-gepa-launch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instruction-set-gepa-launch.d.ts","sourceRoot":"","sources":["../src/instruction-set-gepa-launch.ts"],"names":[],"mappings":"AAsFA,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,gBAAgB,CAiBlB;AAqCD;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,CAAC,UAAU,EAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,GAAG,QAAQ,GACnC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ7B"}
|
|
@@ -1,17 +1,137 @@
|
|
|
1
1
|
import { authedFetch } from './http.js';
|
|
2
|
+
import { MAX_VERSION_NUMBER, parseSpecifier } from './instruction-set-lock/index.js';
|
|
2
3
|
import { parseJsonResponse } from './json-response.js';
|
|
3
|
-
/**
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A version runs and promotes only when its component keys equal the set's
|
|
6
|
+
* current shape exactly: promotion refuses any other key set
|
|
7
|
+
* (instruction_set_candidate_shape_mismatch). Returns null when they match.
|
|
8
|
+
*/
|
|
9
|
+
function shapeDifference(shape, version) {
|
|
10
|
+
const keys = new Set(version.componentKeys ?? []);
|
|
11
|
+
const shapeKeys = new Set(shape);
|
|
12
|
+
const missing = shape.filter(key => !keys.has(key));
|
|
13
|
+
const extra = [...keys].filter(key => !shapeKeys.has(key)).sort();
|
|
14
|
+
return missing.length === 0 && extra.length === 0 ? null : { missing, extra };
|
|
15
|
+
}
|
|
16
|
+
function describeDifference({ missing, extra }) {
|
|
17
|
+
const quote = (keys) => keys.map(key => `"${key}"`).join(', ');
|
|
18
|
+
return [
|
|
19
|
+
...(missing.length > 0 ? [`missing ${quote(missing)}`] : []),
|
|
20
|
+
...(extra.length > 0 ? [`extra ${quote(extra)}`] : []),
|
|
21
|
+
].join('; ');
|
|
22
|
+
}
|
|
23
|
+
function newestMatchingVersion(shape, versions) {
|
|
24
|
+
return versions
|
|
25
|
+
.filter(candidate => Array.isArray(candidate.componentKeys) && shapeDifference(shape, candidate) === null)
|
|
26
|
+
.reduce((max, candidate) => {
|
|
27
|
+
const number = candidate.versionNumber ?? 0;
|
|
28
|
+
return max === null || number > max ? number : max;
|
|
29
|
+
}, null);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* ORI-2128: a version made before a shape change can lack a component of the
|
|
33
|
+
* set's current shape, or carry one the set has since removed. The runner or
|
|
34
|
+
* promotion would refuse it later; refuse it here, before a run is spawned or
|
|
35
|
+
* queued. A server that predates per-version component keys sends none; the
|
|
36
|
+
* runner remains the backstop.
|
|
37
|
+
*/
|
|
38
|
+
function requireMatchingSeed(shape, versions, version, modelConfigIdentity, role) {
|
|
39
|
+
if (!Array.isArray(shape) || !Array.isArray(version.componentKeys))
|
|
40
|
+
return;
|
|
41
|
+
const difference = shapeDifference(shape, version);
|
|
42
|
+
if (difference === null)
|
|
43
|
+
return;
|
|
44
|
+
const newest = newestMatchingVersion(shape, versions);
|
|
45
|
+
const detail = describeDifference(difference);
|
|
46
|
+
if (role === 'production') {
|
|
47
|
+
const newestNote = newest === null ? 'no version of this profile matches it yet' : `newest matching: v${newest}`;
|
|
48
|
+
throw new Error(`instruction_set_profile_production_incomplete: ${modelConfigIdentity} production v${version.versionNumber} does not match the current shape (${detail}); promote a version that matches it, or name one with @vN (${newestNote})`);
|
|
49
|
+
}
|
|
50
|
+
const advice = newest === null
|
|
51
|
+
? 'no version of this profile matches the current shape yet'
|
|
52
|
+
: `pick v${newest}`;
|
|
53
|
+
throw new Error(`instruction_set_profile_version_incomplete: ${modelConfigIdentity} v${version.versionNumber} does not match the current shape (${detail}); ${advice}`);
|
|
54
|
+
}
|
|
55
|
+
function profileVersionNumber(value) {
|
|
56
|
+
const match = /^v?([1-9][0-9]*)$/u.exec(value);
|
|
57
|
+
const versionNumber = match ? Number(match[1]) : Number.NaN;
|
|
58
|
+
if (!Number.isSafeInteger(versionNumber) || versionNumber > MAX_VERSION_NUMBER) {
|
|
59
|
+
throw new Error(`--profile-version must be a version number such as 3 or v3; received ${value}`);
|
|
60
|
+
}
|
|
61
|
+
return versionNumber;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Combine `--instruction-set`, `--model-config` and `--profile-version` into
|
|
65
|
+
* one Seed. A value with `/` or `@` is a specifier (`set/profile@vN`); any
|
|
66
|
+
* other value is a set slug or exact name, passed through unchanged. Values
|
|
67
|
+
* named twice must agree, the same rule `sync` applies to `--version`.
|
|
68
|
+
*/
|
|
69
|
+
export function gepaSeedSelector(instructionSetArg, modelConfigFlag, versionFlag) {
|
|
70
|
+
const flagVersion = versionFlag === undefined ? undefined : profileVersionNumber(versionFlag);
|
|
71
|
+
if (!instructionSetArg.includes('/') && !instructionSetArg.includes('@')) {
|
|
72
|
+
return { instructionSetName: instructionSetArg, modelConfigIdentity: modelConfigFlag, versionNumber: flagVersion };
|
|
73
|
+
}
|
|
74
|
+
const parsed = parseSpecifier(instructionSetArg);
|
|
75
|
+
if (parsed.profile !== undefined && modelConfigFlag !== undefined && parsed.profile !== modelConfigFlag) {
|
|
76
|
+
throw new Error(`instruction_set_seed_conflict: specifier names profile ${parsed.profile} but --model-config is ${modelConfigFlag}`);
|
|
77
|
+
}
|
|
78
|
+
if (parsed.versionNumber !== undefined && flagVersion !== undefined && parsed.versionNumber !== flagVersion) {
|
|
79
|
+
throw new Error(`instruction_set_seed_conflict: specifier names v${parsed.versionNumber} but --profile-version is v${flagVersion}`);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
instructionSetName: parsed.set,
|
|
83
|
+
modelConfigIdentity: parsed.profile ?? modelConfigFlag,
|
|
84
|
+
versionNumber: parsed.versionNumber ?? flagVersion,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the Seed's profile version id: the named version when one is
|
|
89
|
+
* given, otherwise the requested Profile's Production.
|
|
90
|
+
*/
|
|
91
|
+
async function resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project, versionNumber) {
|
|
5
92
|
const response = await authedFetch(`/api/cli/instruction-sets/${encodeURIComponent(instructionSetName)}?project=${encodeURIComponent(project)}`);
|
|
6
93
|
if (!response.ok)
|
|
7
94
|
throw new Error(`Instruction set resolution failed: ${await response.text()}`);
|
|
8
95
|
const payload = await parseJsonResponse(response, 'Instruction set resolution');
|
|
9
96
|
const instructionSet = payload.instructionSet;
|
|
10
97
|
const profile = instructionSet?.profiles?.find(candidate => candidate.modelConfigIdentity === modelConfigIdentity);
|
|
11
|
-
|
|
98
|
+
// An archived model config's profile is not resolvable: the same refusal
|
|
99
|
+
// the server's resolve_instruction_set gives hosted runs.
|
|
100
|
+
if (!profile || profile.modelConfigArchivedAt)
|
|
12
101
|
throw new Error(`instruction_set_profile_not_found: ${modelConfigIdentity}`);
|
|
102
|
+
const versions = profile.versions ?? [];
|
|
103
|
+
if (versionNumber !== undefined) {
|
|
104
|
+
const version = versions.find(candidate => candidate.versionNumber === versionNumber);
|
|
105
|
+
if (version?.profileVersionId) {
|
|
106
|
+
requireMatchingSeed(instructionSet?.shape, versions, version, modelConfigIdentity, 'named');
|
|
107
|
+
return version.profileVersionId;
|
|
108
|
+
}
|
|
109
|
+
const newest = versions.reduce((max, candidate) => Math.max(max, candidate.versionNumber ?? 0), 0);
|
|
110
|
+
throw new Error(`instruction_set_profile_version_not_found: ${modelConfigIdentity} has no v${versionNumber}; ${newest > 0 ? `newest is v${newest}` : 'it has no versions'}`);
|
|
111
|
+
}
|
|
13
112
|
const profileVersionId = profile.production?.profileVersionId;
|
|
14
113
|
if (!profileVersionId)
|
|
15
114
|
throw new Error(`instruction_set_profile_not_promoted: ${modelConfigIdentity}`);
|
|
115
|
+
const production = versions.find(candidate => candidate.profileVersionId === profileVersionId);
|
|
116
|
+
if (production)
|
|
117
|
+
requireMatchingSeed(instructionSet?.shape, versions, production, modelConfigIdentity, 'production');
|
|
16
118
|
return profileVersionId;
|
|
17
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Resolve the Seed that dispatch normalised into the connector environment.
|
|
122
|
+
* Returns undefined when no instruction set was selected. When no version is
|
|
123
|
+
* named, `unversioned: 'production'` resolves the profile's Production here
|
|
124
|
+
* (local runs); `unversioned: 'server'` leaves it to the hosted launch route,
|
|
125
|
+
* which resolves Production itself in the same call that queues the run.
|
|
126
|
+
*/
|
|
127
|
+
export async function resolveGepaSeedFromEnvironment(environment, project, unversioned) {
|
|
128
|
+
const instructionSetName = environment.ORIZU_INSTRUCTION_SET_NAME;
|
|
129
|
+
const modelConfigIdentity = environment.ORIZU_MODEL_CONFIG_IDENTITY;
|
|
130
|
+
if (!instructionSetName || !modelConfigIdentity)
|
|
131
|
+
return undefined;
|
|
132
|
+
const rawVersion = environment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_NUMBER;
|
|
133
|
+
const versionNumber = rawVersion === undefined ? undefined : profileVersionNumber(rawVersion);
|
|
134
|
+
if (versionNumber === undefined && unversioned === 'server')
|
|
135
|
+
return undefined;
|
|
136
|
+
return resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project, versionNumber);
|
|
137
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-report-input.d.ts","sourceRoot":"","sources":["../src/markdown-report-input.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,QAAkB,CAAA;AAsCxD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,cAAc,GAAG,QAAQ,GAAG,MAAM,GAC9C,mBAAmB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"markdown-report-input.d.ts","sourceRoot":"","sources":["../src/markdown-report-input.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,QAAkB,CAAA;AAsCxD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,cAAc,GAAG,QAAQ,GAAG,MAAM,GAC9C,mBAAmB,GAAG,IAAI,CAgD5B"}
|
|
@@ -72,7 +72,7 @@ export function readMarkdownReportInput(args, reportLabel) {
|
|
|
72
72
|
sourceName = 'inline';
|
|
73
73
|
}
|
|
74
74
|
if (!hasCanonicalReportMarkdownContent(markdown)) {
|
|
75
|
-
throw new Error(`${reportLabel} report
|
|
75
|
+
throw new Error(`${reportLabel} report has no visible content: it is empty or contains only whitespace`);
|
|
76
76
|
}
|
|
77
77
|
if (Buffer.byteLength(markdown, 'utf8') > MARKDOWN_REPORT_MAX_BYTES) {
|
|
78
78
|
throw new Error(`${reportLabel} report exceeds ${MARKDOWN_REPORT_MAX_BYTES} bytes`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimizations-promote-cli.d.ts","sourceRoot":"","sources":["../src/optimizations-promote-cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"optimizations-promote-cli.d.ts","sourceRoot":"","sources":["../src/optimizations-promote-cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAClE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CACjE;AAqED,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD1G"}
|
|
@@ -54,6 +54,17 @@ function productionPromotionReplay(runId, candidateId, project, origin) {
|
|
|
54
54
|
: '';
|
|
55
55
|
return `Promote this profile with: orizu${originArguments} optimizations promote ${shellArgument(runId)} --candidate ${shellArgument(candidateId)} --label production --project ${shellArgument(project)}`;
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* ORI-2128: a candidate grown from a Seed older than Production does not
|
|
59
|
+
* contain the changes made since that Seed. Warn; never refuse (ORI-2132).
|
|
60
|
+
*/
|
|
61
|
+
function staleSeedWarningFor(data) {
|
|
62
|
+
const seed = data.runSeedVersionNumber;
|
|
63
|
+
const production = data.productionVersionNumber;
|
|
64
|
+
if (typeof seed !== 'number' || typeof production !== 'number' || seed >= production)
|
|
65
|
+
return null;
|
|
66
|
+
return `Warning: this run started from v${seed}; production is v${production}. Changes made since v${seed} are not in this candidate.`;
|
|
67
|
+
}
|
|
57
68
|
export async function promoteOptimizationCommand(args, io) {
|
|
58
69
|
const runId = args.find(arg => !arg.startsWith('--') && arg !== option(args, '--candidate') && arg !== option(args, '--label') && arg !== option(args, '--project'));
|
|
59
70
|
const candidateId = option(args, '--candidate');
|
|
@@ -72,15 +83,21 @@ export async function promoteOptimizationCommand(args, io) {
|
|
|
72
83
|
const replay = isProfilePromotion && data.appliedLabel !== 'production'
|
|
73
84
|
? productionPromotionReplay(runId, candidateId, project, io.origin)
|
|
74
85
|
: null;
|
|
86
|
+
const staleSeedWarning = isProfilePromotion ? staleSeedWarningFor(data) : null;
|
|
75
87
|
if (io.json) {
|
|
76
88
|
io.print(JSON.stringify(isProfilePromotion
|
|
77
89
|
? {
|
|
78
90
|
profileVersionId: data.profileVersionId,
|
|
79
91
|
versionNumber: data.versionNumber,
|
|
80
92
|
appliedLabel: data.appliedLabel,
|
|
93
|
+
// JSON.stringify omits these when an older server did not send them.
|
|
94
|
+
runSeedVersionNumber: data.runSeedVersionNumber,
|
|
95
|
+
productionVersionNumber: data.productionVersionNumber,
|
|
81
96
|
components: data.components,
|
|
82
97
|
}
|
|
83
98
|
: { promptVersionId: data.promptVersionId }));
|
|
99
|
+
if (staleSeedWarning)
|
|
100
|
+
io.printErr(staleSeedWarning);
|
|
84
101
|
if (isProfilePromotion && data.appliedLabel === undefined) {
|
|
85
102
|
io.printErr(APPLIED_LABEL_VERSION_SKEW_NOTE);
|
|
86
103
|
io.printErr(replay);
|
|
@@ -88,6 +105,8 @@ export async function promoteOptimizationCommand(args, io) {
|
|
|
88
105
|
return;
|
|
89
106
|
}
|
|
90
107
|
if (isProfilePromotion) {
|
|
108
|
+
if (staleSeedWarning)
|
|
109
|
+
io.printErr(staleSeedWarning);
|
|
91
110
|
io.print(`Promoted profile version ${sanitizeTerminalText(data.profileVersionId)}`);
|
|
92
111
|
if (data.appliedLabel === undefined) {
|
|
93
112
|
io.printErr(APPLIED_LABEL_VERSION_SKEW_NOTE);
|
|
@@ -47,6 +47,13 @@ interface PreviewPage {
|
|
|
47
47
|
on?: (event: string, listener: () => void) => unknown;
|
|
48
48
|
off?: (event: string, listener: () => void) => unknown;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Removes line and block comments, walking left to right so a `//` or `/*`
|
|
52
|
+
* inside a quoted string or template literal is left alone. A block comment
|
|
53
|
+
* keeps its newlines, so line numbers in later messages stay true.
|
|
54
|
+
* Regex literals are not tracked; a quote inside one can hide a comment.
|
|
55
|
+
*/
|
|
56
|
+
export declare function stripComments(code: string): string;
|
|
50
57
|
export declare function validatePreviewInputs(options: AppPreviewOptions): Issue[];
|
|
51
58
|
export declare function runLocalAppPreview(options: AppPreviewOptions): Promise<AppPreviewResult>;
|
|
52
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-runtime.d.ts","sourceRoot":"","sources":["../src/preview-runtime.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"preview-runtime.d.ts","sourceRoot":"","sources":["../src/preview-runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/preview-runtime.js
CHANGED
|
@@ -57,9 +57,56 @@ function isNodeError(error) {
|
|
|
57
57
|
return error instanceof Error;
|
|
58
58
|
}
|
|
59
59
|
const SUPPORTED_SCHEMA_KEYS = new Set(['type', 'required', 'properties', 'items', 'enum']);
|
|
60
|
+
/**
|
|
61
|
+
* Removes line and block comments, walking left to right so a `//` or `/*`
|
|
62
|
+
* inside a quoted string or template literal is left alone. A block comment
|
|
63
|
+
* keeps its newlines, so line numbers in later messages stay true.
|
|
64
|
+
* Regex literals are not tracked; a quote inside one can hide a comment.
|
|
65
|
+
*/
|
|
66
|
+
export function stripComments(code) {
|
|
67
|
+
let out = '';
|
|
68
|
+
let quote = '';
|
|
69
|
+
let i = 0;
|
|
70
|
+
while (i < code.length) {
|
|
71
|
+
const char = code[i];
|
|
72
|
+
const next = code[i + 1];
|
|
73
|
+
if (quote) {
|
|
74
|
+
out += char;
|
|
75
|
+
if (char === '\\' && next !== undefined) {
|
|
76
|
+
out += next;
|
|
77
|
+
i += 2;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// Single and double quoted strings end at the line's end; templates may span lines.
|
|
81
|
+
if (char === quote || (char === '\n' && quote !== '`'))
|
|
82
|
+
quote = '';
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
else if (char === '"' || char === "'" || char === '`') {
|
|
86
|
+
quote = char;
|
|
87
|
+
out += char;
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
else if (char === '/' && next === '/' && code[i - 1] !== ':') {
|
|
91
|
+
while (i < code.length && code[i] !== '\n')
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
else if (char === '/' && next === '*') {
|
|
95
|
+
const close = code.indexOf('*/', i + 2);
|
|
96
|
+
const end = close === -1 ? code.length : close + 2;
|
|
97
|
+
out += code.slice(i, end).replace(/[^\n]/g, ' ');
|
|
98
|
+
i = end;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
out += char;
|
|
102
|
+
i++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
60
107
|
export function validatePreviewInputs(options) {
|
|
61
108
|
const issues = [];
|
|
62
|
-
const source = readFileSync(options.filePath, 'utf8');
|
|
109
|
+
const source = stripComments(readFileSync(options.filePath, 'utf8'));
|
|
63
110
|
validateImports(source, issues);
|
|
64
111
|
validateDefaultExport(source, options.componentName, issues);
|
|
65
112
|
validateSchema(options.inputSchema, 'input schema', issues);
|
|
@@ -296,10 +343,7 @@ function resolveDefaultExport(source) {
|
|
|
296
343
|
return null;
|
|
297
344
|
}
|
|
298
345
|
function unwrapDefaultExportExpression(expression) {
|
|
299
|
-
const trimmed = expression
|
|
300
|
-
.replace(/\/\*[\s\S]*?\*\/\s*$/, '')
|
|
301
|
-
.replace(/\/\/.*$/, '')
|
|
302
|
-
.trim();
|
|
346
|
+
const trimmed = expression.trim();
|
|
303
347
|
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(trimmed)) {
|
|
304
348
|
return trimmed;
|
|
305
349
|
}
|
|
@@ -13,11 +13,11 @@ export const RESERVED_CREDENTIAL_ENVS = new Set([
|
|
|
13
13
|
'GEMINI_API_KEY', // Historical SQL reservation; removing local forwarding does not release this name.
|
|
14
14
|
'GOOGLE_API_KEY', // Historical SQL reservation for the Google alias, independent of run providers.
|
|
15
15
|
'ALI_1505_ENDPOINT_OVERRIDE_API_KEY', // hosted-optimization.ts: runner-injected secret.
|
|
16
|
-
'BRAINTRUST_API_KEY', //
|
|
16
|
+
'BRAINTRUST_API_KEY', // lib/hosted-connectors.ts: workbench connector.
|
|
17
17
|
'CF_API_KEY', // test/with-cloudflare-env.test.ts: Cloudflare spelling.
|
|
18
18
|
'CLOUDFLARE_API_KEY', // test/with-cloudflare-env.test.ts: Cloudflare spelling.
|
|
19
19
|
'DAYTONA_API_KEY', // scripts/daytona-workbench-slice.mjs: hosted sandbox.
|
|
20
|
-
'INTERNAL_API_KEY', //
|
|
20
|
+
'INTERNAL_API_KEY', // Historical SQL reservation; the internal compile route is gone (ORI-2305).
|
|
21
21
|
'LINEAR_API_KEY', // lib/services/linear-feedback.ts: issue service.
|
|
22
22
|
'RESEND_API_KEY', // lib/services/email.ts: email delivery.
|
|
23
23
|
]);
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matches any content character. `\uXXXX` names each code point, so
|
|
3
|
+
* JavaScript (with the `u` flag) and PostgreSQL's `~` read it identically and
|
|
4
|
+
* no locale is involved.
|
|
5
|
+
*/
|
|
6
|
+
export declare const REPORT_MARKDOWN_CONTENT_PATTERN: string;
|
|
1
7
|
export declare function hasCanonicalReportMarkdownContent(markdown: string): boolean;
|
|
2
8
|
//# sourceMappingURL=report-markdown-blankness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-markdown-blankness.d.ts","sourceRoot":"","sources":["../src/report-markdown-blankness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report-markdown-blankness.d.ts","sourceRoot":"","sources":["../src/report-markdown-blankness.ts"],"names":[],"mappings":"AA+CA;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,QAE/B,CAAA;AAIb,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3E"}
|
|
@@ -1,6 +1,49 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// ADR-036: the one definition of an empty report, shared by the CLI, the web
|
|
2
|
+
// app's readers and upload route, and the timeline's Data API filter. The
|
|
3
|
+
// database writer and comment trigger use private.report_markdown_has_content,
|
|
4
|
+
// whose pattern is REPORT_MARKDOWN_CONTENT_PATTERN verbatim (a database test
|
|
5
|
+
// pins that). Before ADR-036 these sites copied PostgreSQL 15's locale answer
|
|
6
|
+
// while production ran 17, so the CLI accepted reports the writer rejected.
|
|
7
|
+
/**
|
|
8
|
+
* The characters a report may consist of and still be empty: Unicode's
|
|
9
|
+
* White_Space property plus the four C0 information separators. Everything
|
|
10
|
+
* else, including invisible format characters such as U+FEFF, is content.
|
|
11
|
+
*/
|
|
12
|
+
const REPORT_BLANK_CODE_POINTS = [
|
|
13
|
+
// Tab, line feed, vertical tab, form feed, carriage return.
|
|
14
|
+
{ first: 0x0009, last: 0x000d },
|
|
15
|
+
// File, group, record and unit separators: not Unicode whitespace, but
|
|
16
|
+
// invisible, and blank in production since it has run PostgreSQL 17.
|
|
17
|
+
{ first: 0x001c, last: 0x001f },
|
|
18
|
+
// Space.
|
|
19
|
+
{ first: 0x0020, last: 0x0020 },
|
|
20
|
+
// Next line.
|
|
21
|
+
{ first: 0x0085, last: 0x0085 },
|
|
22
|
+
// No-break space.
|
|
23
|
+
{ first: 0x00a0, last: 0x00a0 },
|
|
24
|
+
// Ogham space mark.
|
|
25
|
+
{ first: 0x1680, last: 0x1680 },
|
|
26
|
+
// En quad through hair space, including figure space U+2007.
|
|
27
|
+
{ first: 0x2000, last: 0x200a },
|
|
28
|
+
// Line separator and paragraph separator.
|
|
29
|
+
{ first: 0x2028, last: 0x2029 },
|
|
30
|
+
// Narrow no-break space.
|
|
31
|
+
{ first: 0x202f, last: 0x202f },
|
|
32
|
+
// Medium mathematical space.
|
|
33
|
+
{ first: 0x205f, last: 0x205f },
|
|
34
|
+
// Ideographic space.
|
|
35
|
+
{ first: 0x3000, last: 0x3000 },
|
|
36
|
+
];
|
|
37
|
+
function escapeCodePoint(codePoint) {
|
|
38
|
+
return `\\u${codePoint.toString(16).padStart(4, '0')}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Matches any content character. `\uXXXX` names each code point, so
|
|
42
|
+
* JavaScript (with the `u` flag) and PostgreSQL's `~` read it identically and
|
|
43
|
+
* no locale is involved.
|
|
44
|
+
*/
|
|
45
|
+
export const REPORT_MARKDOWN_CONTENT_PATTERN = `[^${REPORT_BLANK_CODE_POINTS.map(({ first, last }) => first === last ? escapeCodePoint(first) : `${escapeCodePoint(first)}-${escapeCodePoint(last)}`).join('')}]`;
|
|
46
|
+
const REPORT_MARKDOWN_CONTENT = new RegExp(REPORT_MARKDOWN_CONTENT_PATTERN, 'u');
|
|
4
47
|
export function hasCanonicalReportMarkdownContent(markdown) {
|
|
5
|
-
return
|
|
48
|
+
return REPORT_MARKDOWN_CONTENT.test(markdown);
|
|
6
49
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ORI-2128: what `optimizations promote` needs to warn about a stale seed.
|
|
3
|
+
* The run's seed version number, and its profile's production version number
|
|
4
|
+
* as it stood before this promotion (null when the profile had none).
|
|
5
|
+
* Shared by the promote handler, both promote routes, and the CLI.
|
|
6
|
+
*/
|
|
7
|
+
export interface SeedAgainstProduction {
|
|
8
|
+
runSeedVersionNumber: number;
|
|
9
|
+
productionVersionNumber: number | null;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=seed-against-production.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed-against-production.d.ts","sourceRoot":"","sources":["../src/seed-against-production.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-and-skills-commands.d.ts","sourceRoot":"","sources":["../src/setup-and-skills-commands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup-and-skills-commands.d.ts","sourceRoot":"","sources":["../src/setup-and-skills-commands.ts"],"names":[],"mappings":"AA+EA,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAW,MAAM,wBAAwB,CAAA;AAMjF,iBAAe,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAY/E;AA0cD,iBAAe,mBAAmB,kBA+BjC;AAwFD,iBAAS,mBAAmB,SAmD3B;AAED,iBAAe,mBAAmB,kBA0DjC;AAED,iBAAS,iBAAiB,SAgBzB;AAMD,iBAAe,gBAAgB,CAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,OAAO,EACf,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,OAAO,GAAE,oBAAkC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAiDf;AAqID,iBAAe,YAAY,kBAqX1B;AAED,iBAAS,kBAAkB,SAS1B;AAED,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,GACT,CAAA"}
|