@orchestraworks/cli 0.3.0 → 0.5.0
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 +20 -1257
- package/dist/cli/core/invocation.js +1 -1
- package/dist/cli/factory/init.d.ts +1 -1
- package/dist/cli/factory/init.js +41 -13
- package/dist/cli/main.js +0 -0
- package/dist/cli/skill.js +20 -7
- package/docs/REFERENCE.md +1278 -0
- package/node_modules/@orchestraworks/client/package.json +1 -1
- package/package.json +7 -8
- package/skills/orchestra/SKILL.md +29 -3
- package/skills/orchestra-fdk/SKILL.md +68 -10
- package/skills/orchestra-fdk/references/authoring.md +14 -14
- package/templates/bug-fix/tsconfig.json +12 -0
- package/templates/engineering-team/lib/setup.sh +16 -0
- package/templates/engineering-team/package.json +1 -1
- package/templates/todo-factory/package.json +1 -1
- package/node_modules/@orchestraworks/workflow-render/LICENSE +0 -202
- package/node_modules/@orchestraworks/workflow-render/dist/constants.d.ts +0 -98
- package/node_modules/@orchestraworks/workflow-render/dist/context.d.ts +0 -37
- package/node_modules/@orchestraworks/workflow-render/dist/geometry-core.d.ts +0 -40
- package/node_modules/@orchestraworks/workflow-render/dist/graph-digest.d.ts +0 -4
- package/node_modules/@orchestraworks/workflow-render/dist/grid.d.ts +0 -33
- package/node_modules/@orchestraworks/workflow-render/dist/heuristic.d.ts +0 -7
- package/node_modules/@orchestraworks/workflow-render/dist/identity.d.ts +0 -9
- package/node_modules/@orchestraworks/workflow-render/dist/index.d.ts +0 -24
- package/node_modules/@orchestraworks/workflow-render/dist/index.js +0 -1
- package/node_modules/@orchestraworks/workflow-render/dist/layout.d.ts +0 -6
- package/node_modules/@orchestraworks/workflow-render/dist/normalize.d.ts +0 -33
- package/node_modules/@orchestraworks/workflow-render/dist/place.d.ts +0 -81
- package/node_modules/@orchestraworks/workflow-render/dist/ports.d.ts +0 -15
- package/node_modules/@orchestraworks/workflow-render/dist/presence.d.ts +0 -6
- package/node_modules/@orchestraworks/workflow-render/dist/route-cells.d.ts +0 -15
- package/node_modules/@orchestraworks/workflow-render/dist/sha256.d.ts +0 -3
- package/node_modules/@orchestraworks/workflow-render/dist/svg.d.ts +0 -7
- package/node_modules/@orchestraworks/workflow-render/dist/text.d.ts +0 -14
- package/node_modules/@orchestraworks/workflow-render/dist/types.d.ts +0 -310
- package/node_modules/@orchestraworks/workflow-render/dist/verify.d.ts +0 -26
- package/node_modules/@orchestraworks/workflow-render/package.json +0 -42
|
@@ -14,7 +14,7 @@ import { errorCode } from "./errors.js";
|
|
|
14
14
|
export function addAuthOptions(command) {
|
|
15
15
|
return command
|
|
16
16
|
.option("--profile <name>", "named auth profile to read (default profile if omitted)")
|
|
17
|
-
.option("--base-url <url>", "platform base URL (overrides PLATFORM_BASE_URL and the stored profile)")
|
|
17
|
+
.option("--base-url <url>", "platform base URL (overrides ORCHESTRA_BASE_URL, PLATFORM_BASE_URL and the stored profile)")
|
|
18
18
|
.option("--org <id>", "target organization id (overrides ORCHESTRA_ORGANIZATION_ID and the stored profile)");
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
@@ -13,7 +13,7 @@ type ModelKeyChoice = Exclude<TemplateChoice, "credits">;
|
|
|
13
13
|
/** What `--model-key` takes. */
|
|
14
14
|
export declare const MODEL_KEY_CHOICES: readonly ModelKeyChoice[];
|
|
15
15
|
/** Every file the starter writes besides package.json, in the order it prints them. */
|
|
16
|
-
export declare const STARTER_FILES: readonly ["fdk.json", "main.ts", "image/Dockerfile", "image/setup.sh", "agents/bugfix.md", "skills/codebase/SKILL.md"];
|
|
16
|
+
export declare const STARTER_FILES: readonly ["fdk.json", "tsconfig.json", "main.ts", "image/Dockerfile", "image/setup.sh", "agents/bugfix.md", "skills/codebase/SKILL.md"];
|
|
17
17
|
/** The starter plain `orchestra fdk init` writes, and the only one `--repository` and `--model-key` fill in. */
|
|
18
18
|
export declare const DEFAULT_TEMPLATE = "bug-fix";
|
|
19
19
|
/** The starters `--template` offers by name. Each is a folder under templates/ that brings its own package.json. */
|
package/dist/cli/factory/init.js
CHANGED
|
@@ -13,6 +13,7 @@ export const MODEL_KEY_CHOICES = TEMPLATE_CHOICES.filter((choice) => choice !==
|
|
|
13
13
|
/** Every file the starter writes besides package.json, in the order it prints them. */
|
|
14
14
|
export const STARTER_FILES = [
|
|
15
15
|
"fdk.json",
|
|
16
|
+
"tsconfig.json",
|
|
16
17
|
"main.ts",
|
|
17
18
|
"image/Dockerfile",
|
|
18
19
|
"image/setup.sh",
|
|
@@ -27,8 +28,12 @@ const TEMPLATES_DIR = "templates";
|
|
|
27
28
|
const TEMPLATE_DIR = join(TEMPLATES_DIR, DEFAULT_TEMPLATE);
|
|
28
29
|
/** The one template file `init` fills in; every other file is copied as it is. */
|
|
29
30
|
const FILLED_FILE = "main.ts";
|
|
31
|
+
/** What runs main.ts and checks its types; each is added at the range the kit itself is built with. */
|
|
32
|
+
const STARTER_DEV_PACKAGES = ["tsx", "typescript", "@types/node"];
|
|
33
|
+
/** The script the starter adds when package.json has none of that name. */
|
|
34
|
+
const TYPECHECK_SCRIPT = { name: "typecheck", command: "tsc -p tsconfig.json" };
|
|
30
35
|
/** Any other package in package.json means the folder is a codebase rather than a new folder beside one. */
|
|
31
|
-
const PACKAGES_ALLOWED = new Set([KIT_PACKAGE_NAME,
|
|
36
|
+
const PACKAGES_ALLOWED = new Set([KIT_PACKAGE_NAME, ...STARTER_DEV_PACKAGES]);
|
|
32
37
|
const DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
|
|
33
38
|
/** Leaves room for the longest construct path the template declares, so every derived slug stays within 60. */
|
|
34
39
|
const FACTORY_NAME_MAX = 30;
|
|
@@ -90,15 +95,24 @@ export async function initCommand(options, io = defaultIo) {
|
|
|
90
95
|
};
|
|
91
96
|
});
|
|
92
97
|
const record = manifest.kind === "object" ? manifest.record : {};
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
98
|
+
const added = STARTER_DEV_PACKAGES.filter((name) => !listsPackage(record, name));
|
|
99
|
+
const ranges = kitDevRanges(packageRoot, added);
|
|
100
|
+
const devDependencies = { ...dependencyMap(record, "devDependencies"), ...ranges };
|
|
101
|
+
// A `scripts` that is not an object is left as it is rather than replaced.
|
|
102
|
+
const addsTypecheck = record.scripts === undefined || (isRecord(record.scripts) && record.scripts[TYPECHECK_SCRIPT.name] === undefined);
|
|
103
|
+
const scripts = dependencyMap(record, "scripts");
|
|
104
|
+
const merged = {
|
|
105
|
+
...record,
|
|
106
|
+
type: "module",
|
|
107
|
+
...(addsTypecheck ? { scripts: { ...scripts, [TYPECHECK_SCRIPT.name]: TYPECHECK_SCRIPT.command } } : {}),
|
|
108
|
+
...(added.length > 0 ? { devDependencies } : {}),
|
|
109
|
+
};
|
|
96
110
|
writeFileSync(manifestPath, `${JSON.stringify(merged, null, 2)}\n`);
|
|
97
111
|
for (const { path, text } of contents) {
|
|
98
112
|
mkdirSync(dirname(join(dir, path)), { recursive: true });
|
|
99
113
|
writeFileSync(join(dir, path), text);
|
|
100
114
|
}
|
|
101
|
-
printNextSteps(io, { repository: repository.full, factoryName, choice, dir,
|
|
115
|
+
printNextSteps(io, { repository: repository.full, factoryName, choice, dir, added, addsTypecheck });
|
|
102
116
|
}
|
|
103
117
|
/** The starters this kit carries: one folder each under templates/. */
|
|
104
118
|
export function availableTemplates(packageRoot = runningPackageRoot()) {
|
|
@@ -325,14 +339,19 @@ function dependencyMap(record, field) {
|
|
|
325
339
|
const value = record[field];
|
|
326
340
|
return isRecord(value) ? value : {};
|
|
327
341
|
}
|
|
328
|
-
/** The
|
|
329
|
-
function
|
|
342
|
+
/** The ranges the kit itself is built and tested with, so the starter runs and type-checks on what the kit was proven on. */
|
|
343
|
+
function kitDevRanges(packageRoot, names) {
|
|
330
344
|
const manifest = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8"));
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
345
|
+
const kitDev = isRecord(manifest) ? dependencyMap(manifest, "devDependencies") : {};
|
|
346
|
+
const ranges = {};
|
|
347
|
+
for (const name of names) {
|
|
348
|
+
const range = kitDev[name];
|
|
349
|
+
if (typeof range !== "string") {
|
|
350
|
+
throw new Error(`this orchestra install names no ${name} version to add. Reinstall the kit, then run orchestra fdk init again.`);
|
|
351
|
+
}
|
|
352
|
+
ranges[name] = range;
|
|
334
353
|
}
|
|
335
|
-
return
|
|
354
|
+
return ranges;
|
|
336
355
|
}
|
|
337
356
|
function isRecord(value) {
|
|
338
357
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -341,12 +360,17 @@ function printNextSteps(io, written) {
|
|
|
341
360
|
const inputs = [...SHELL_INPUTS, ...(written.choice === "credits" ? [] : [MODEL_KEY_INPUTS[written.choice]])];
|
|
342
361
|
const width = Math.max(...inputs.map(([name]) => name.length)) + 2;
|
|
343
362
|
io.out(`Wrote a bug-fix factory named '${written.factoryName}' for ${written.repository} into ${written.dir}:`);
|
|
344
|
-
|
|
363
|
+
const changes = [
|
|
364
|
+
`set "type": "module"`,
|
|
365
|
+
...(written.addsTypecheck ? [`added the ${TYPECHECK_SCRIPT.name} script`] : []),
|
|
366
|
+
...(written.added.length > 0 ? [`added ${listed(written.added)} to devDependencies`] : []),
|
|
367
|
+
];
|
|
368
|
+
io.out(` package.json (${changes.join(", ")})`);
|
|
345
369
|
for (const path of STARTER_FILES)
|
|
346
370
|
io.out(` ${path}`);
|
|
347
371
|
io.out("");
|
|
348
372
|
io.out("Next, in this folder:");
|
|
349
|
-
io.out(" 1. npm install");
|
|
373
|
+
io.out(" 1. npm install, then npm run typecheck");
|
|
350
374
|
io.out(" 2. In the shell that runs orchestra, set these values. The platform's team hands them over until image");
|
|
351
375
|
io.out(" hosting exists:");
|
|
352
376
|
for (const [name, what] of inputs)
|
|
@@ -356,3 +380,7 @@ function printNextSteps(io, written) {
|
|
|
356
380
|
io.out(" 3. npx orchestra fdk diff");
|
|
357
381
|
io.out(" 4. npx orchestra fdk apply, then open the GitHub App install link it prints. It waits for the install.");
|
|
358
382
|
}
|
|
383
|
+
/** `a`, `a and b`, or `a, b and c`. */
|
|
384
|
+
function listed(names) {
|
|
385
|
+
return names.length === 1 ? names[0] : `${names.slice(0, -1).join(", ")} and ${names[names.length - 1]}`;
|
|
386
|
+
}
|
package/dist/cli/main.js
CHANGED
|
File without changes
|
package/dist/cli/skill.js
CHANGED
|
@@ -21,8 +21,17 @@ const LINKABLE_HARNESSES = ["claude", "codex"];
|
|
|
21
21
|
const HARNESS_LABEL = { claude: "Claude Code", codex: "Codex" };
|
|
22
22
|
const HARNESS_VALUES = ["claude", "codex", "both", "other"];
|
|
23
23
|
const SCOPE_VALUES = ["user", "project"];
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* How a person keeps the linked skills current: the install the links point into is updated in place, so the
|
|
26
|
+
* command matches where the running package sits. A checkout outside both reads as global, the common case.
|
|
27
|
+
*/
|
|
28
|
+
function updateCommand(running) {
|
|
29
|
+
return running.kind === "project" ? `npm update ${KIT_INSTALL_SPEC}` : `npm update -g ${KIT_INSTALL_SPEC}`;
|
|
30
|
+
}
|
|
31
|
+
/** The folder whose `node_modules` holds a project install: `<folder>/node_modules/@orchestraworks/cli`. */
|
|
32
|
+
function installFolder(packageRoot) {
|
|
33
|
+
return dirname(dirname(dirname(packageRoot)));
|
|
34
|
+
}
|
|
26
35
|
export async function skillInstallCommand(options, deps = {}) {
|
|
27
36
|
const io = deps.io ?? defaultIo;
|
|
28
37
|
const env = deps.env ?? process.env;
|
|
@@ -90,14 +99,18 @@ export async function skillInstallCommand(options, deps = {}) {
|
|
|
90
99
|
return;
|
|
91
100
|
}
|
|
92
101
|
io.out("");
|
|
93
|
-
printSkillFiles(io, running
|
|
102
|
+
printSkillFiles(io, running);
|
|
94
103
|
}
|
|
95
104
|
/** The step after the links: a harness loads a new skill only at its next start, so read them now. */
|
|
96
|
-
function printSkillFiles(io,
|
|
105
|
+
function printSkillFiles(io, running) {
|
|
97
106
|
io.out("Read each skill now; your harness loads new skills only at its next start:");
|
|
98
107
|
for (const skill of KIT_SKILLS)
|
|
99
|
-
io.out(` ${skillFileIn(packageRoot, skill)}`);
|
|
100
|
-
io.out(
|
|
108
|
+
io.out(` ${skillFileIn(running.packageRoot, skill)}`);
|
|
109
|
+
io.out("The kit may be installed globally or in the factory folder.");
|
|
110
|
+
io.out(running.kind === "project"
|
|
111
|
+
? `This one is installed in ${installFolder(running.packageRoot)}, so \`${updateCommand(running)}\`, run in ` +
|
|
112
|
+
`that folder, keeps them current.`
|
|
113
|
+
: `This one is installed globally, so \`${updateCommand(running)}\` keeps them current.`);
|
|
101
114
|
}
|
|
102
115
|
function parseChoice(raw, allowed, flag) {
|
|
103
116
|
if (raw === undefined) {
|
|
@@ -194,7 +207,7 @@ function printPointingInstructions(io, running, anchors, fs) {
|
|
|
194
207
|
for (const file of skillFiles)
|
|
195
208
|
io.out(` ${file}`);
|
|
196
209
|
io.out("");
|
|
197
|
-
io.out(`Point your harness at each directory (a link keeps it current across '${
|
|
210
|
+
io.out(`Point your harness at each directory (a link keeps it current across '${updateCommand(running)}'):`);
|
|
198
211
|
for (const harness of LINKABLE_HARNESSES) {
|
|
199
212
|
// The project leg prints the RELATIVE target the command itself would write, so a hand-made link
|
|
200
213
|
// travels with the repo exactly like an installed one. Nothing recomputes after this line — the
|