Skip to content

Commit 4f77573

Browse files
authored
Merge pull request #8 from APIOpsCycles/method-engine-for-better-flow
Method engine for better flow, station criteria improvements and new stakeholder list and mapping to statiosn
2 parents 09c0da4 + 12bd153 commit 4f77573

57 files changed

Lines changed: 3843 additions & 326 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## Create a new APIOps project (CLI)
2+
3+
4+
```bash
5+
npm create apiops@latest
6+
```
7+
8+
This command runs the `create-apiops` initializer package and generates a starter APIOps project template in your current directory.
9+
10+
11+
112
# APIOps Cycles Method
213

314
This repository contains the source for the APIOps Cycles method, including resources such as canvases. It can be used for multiple purposes, such as the method website (https://www.apiopscycles.com/), which is generated from these files, and the Canvas Creator tool that allows creating, importing and exporting the canvases, and provides a UI. (https://canvascreator.apiopscycles.com/).
@@ -13,24 +24,61 @@ APIOps and APIOps Cycles are trademarks owned by Osaango Oy (https://www.osaango
1324
```
1425
├── src/
1526
│ ├── assets/ # APIOps Cycles logos and other core assets which you might need in your tooling or product
27+
│ ├── lib/ # Method-engine, "walks" developer or AI through the method starting from needs, also used by the CLI when using the create apiops template
1628
│ ├── data/method/ # The Method JSON files (structure, relationship, and guideline content)
1729
│ ├── data/method/canvas/ # The Canvases included in the method as JSON files (also used by tools like Canvas Creator)
1830
│ ├── snippets/ # Raw markdown files used for long content for resource docs (only essential extensions for the json files)
1931
├── scripts/ # Utility scripts
2032
└── package.json
33+
├── skills/ # AI skills that help use the method to design APIs
34+
├── packages/
35+
└── create-apiops # scaffolding template published as node module. Starts a new guided API design project with `npm create apiops@latest`
2136
```
2237

23-
## Requirements
38+
## Integrating the method in to tools, and developer workflows
2439

25-
You can use the JSON files as is and download a .zip file or clone the repository. You can also install them using `npm install apiops-cycles-method-data`.
40+
You can use the JSON files as is and download a .zip file or clone the repository. You can also install them using `npm install apiops-cycles-method-data`, or create a new API design and/or development project with `npm create apiops@latest`
2641

2742
The module exposes top-level exports so you can import the data files directly, for example:
2843

2944
```js
3045
import stations from "apiops-cycles-method-data/method/stations.json";
3146
import canvasData from "apiops-cycles-method-data/canvasData.json";
47+
import {
48+
buildStartData,
49+
buildStationResourceData,
50+
generateCanvases
51+
} from "apiops-cycles-method-data/method-engine";
3252
```
3353

54+
The `method-engine` export is intended for reusable APIOps workflow logic. It gives CLIs, AI agents, apps, and APIs the same station recommendation, resource lookup, and canvas generation behavior without reimplementing the method rules.
55+
56+
The method now also includes reusable stakeholder data:
57+
58+
- `src/data/method/stakeholders.json` defines the shared stakeholder catalog
59+
- `src/data/method/station-stakeholders.json` maps each station to weighted stakeholder participation
60+
- `src/data/method/<locale>/labels.stakeholders.json` stores localized stakeholder titles, descriptions, and involvement labels
61+
62+
Stakeholder involvement uses three lightweight levels:
63+
64+
- `lead`
65+
- `core`
66+
- `consulted`
67+
68+
This is meant to keep APIOps Cycles explicitly cross-functional, including business, security, compliance, support, and consumer voices in architecture and design work where relevant.
69+
70+
Sticky note authoring should use the shared palette exposed by the method engine:
71+
72+
- `benefit`: `#C0EB6A`
73+
- `neutral`: `#DFDDC5`
74+
- `negative`: `#FFAFAF`
75+
- `task`: `#7DC9E7`
76+
- `default`: `#FFF399`
77+
78+
Prefer section-appropriate defaults when the intent is obvious from the canvas structure.
79+
If a note does not fit a clear intent yet, use the generic default rather than guessing.
80+
When using the interactive CLI, explicit note tags such as `[benefit]`, `[task]`, or `[color=#7DC9E7]` are the supported way to override the section default.
81+
3482
Validate the files locally with:
3583

3684
```bash
@@ -46,16 +94,6 @@ Install dependencies once with:
4694
npm install
4795
```
4896

49-
## Create a new APIOps project (CLI)
50-
51-
Once `create-apiops` is published to npm, you can scaffold a new project with:
52-
53-
```bash
54-
npm create apiops@latest
55-
```
56-
57-
This command runs the `create-apiops` initializer package and generates a starter APIOps project template in your current directory.
58-
5997
## Contributing
6098

6199
### Reporting issues or requesting features
@@ -64,16 +102,17 @@ If you spot a problem in the documentation or have an idea for new content, plea
64102

65103
### Editing or adding content
66104

67-
The main method files (instructions, guidelines, method structure) is located in the the JSON files at `src/data/method/`. These base files (`lines.json`, `stations.json`, `resources.json`, `criteria.json` and `station-criteria.json`) are not localized and live at the root of the folder. Textual values in them reference label keys. English labels are in `src/data/method/en-US` and translations are provided in `labels.lines.json`, `labels.stations.json`, `labels.resources.json` and `labels.criteria.json` under each locale folder. Some longer or more complex resource pages like the API Audit Checklist also use markdown snippets `src/snippets/` linked to the `resources.json`. Do not use any frontmatter in the snippet files. Any supported markdown markup is ok. See references from [Starlight markdown reference](https://starlight.astro.build/guides/authoring-content/) and [Extended markdown reference](https://www.markdownguide.org/extended-syntax/).
105+
The main method content files (instructions, guidelines, method structure) are located in the JSON files at `src/data/method/`. These base files (`lines.json`, `stations.json`, `resources.json`, `criteria.json`, `station-criteria.json`, `stakeholders.json`, and `station-stakeholders.json`) are not localized and live at the root of the folder. Textual values in them reference label keys. English labels are in `src/data/method/en` and translations are provided in `labels.lines.json`, `labels.stations.json`, `labels.resources.json`, `labels.criteria.json`, and `labels.stakeholders.json` under each locale folder. Some longer or more complex resource pages like the API Audit Checklist also use markdown snippets `src/snippets/` linked to the `resources.json`. Do not use any frontmatter in the snippet files. Any supported markdown markup is ok. See references from [Starlight markdown reference](https://starlight.astro.build/guides/authoring-content/) and [Extended markdown reference](https://www.markdownguide.org/extended-syntax/).
68106

69-
Each station links to specific entry criteria followed by the next core station's criteria as exit criteria.`criteria.json`, `station-criteria.json` and `labels.criteria.json`
107+
Each station links to specific entry criteria followed by the next core station's criteria as exit criteria. Stakeholder participation is modeled separately through `stakeholders.json`, `station-stakeholders.json`, and `labels.stakeholders.json`.
70108

71109
#### Editing existing content of Method pages (metrolines, core- and substations, resources).
72110
1. Go to `src/data/method/en` and edit the content in English (English is considered the master langauge, and for the translations to work for other languages, it must always be the first to be edited).
73111
2. Validate that your changes work by running the schema validations (`npm test`)
74112
3. Follow the translation guide if you are able to translate the content to other languages manually or automatically.
75-
4. Commit your code and make a pull request.
76-
5. If you were not able to create the translations of your changes to all languages, create an issue for in the repository for the translations.
113+
4. Update all supported locales before considering the change complete. This includes criteria wording and stakeholder labels when those are touched.
114+
5. Commit your code and make a pull request.
115+
6. If you were not able to create the translations of your changes to all languages, create an issue in the repository for the translations.
77116

78117
#### Translating the language manually or with automated services (new or existing languages with new or changed content)
79118

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{
22
"name": "apiops-cycles-method-data",
3-
"version": "3.3.0",
3+
"version": "3.3.1",
44
"description": "APIOps Cycles Method data and canvases",
55
"license": "Apache-2.0",
66
"type": "module",
77
"files": [
88
"skills",
99
"AGENTS.md",
10+
"src/lib",
1011
"src/data",
1112
"src/snippets",
1213
"src/assets/",
@@ -17,14 +18,17 @@
1718
"packages/*"
1819
],
1920
"exports": {
21+
"./method-engine": "./src/lib/method-engine.js",
2022
"./canvasData.json": "./src/data/canvas/canvasData.json",
2123
"./localizedData.json": "./src/data/canvas/localizedData.json",
2224
"./method/stations.json": "./src/data/method/stations.json",
2325
"./method/resources.json": "./src/data/method/resources.json",
24-
"./method/station-criteria.json": "./src/data/method/station-criteria.json"
26+
"./method/station-criteria.json": "./src/data/method/station-criteria.json",
27+
"./method/stakeholders.json": "./src/data/method/stakeholders.json",
28+
"./method/station-stakeholders.json": "./src/data/method/station-stakeholders.json"
2529
},
2630
"scripts": {
27-
"test": "node scripts/validate.mjs",
31+
"test": "node scripts/validate.mjs && node scripts/test-method-stakeholders.mjs && node scripts/test-note-colors.mjs && node scripts/test-print-method-snippet.mjs",
2832
"release:create-apiops:pack": "npm pack --workspace packages/create-apiops",
2933
"release:create-apiops:publish": "npm publish --workspace packages/create-apiops --access public",
3034
"check:packaging:skills": "node scripts/check-packaging-skills.mjs",

packages/create-apiops/bin/create-apiops-project.js

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ function replaceInFile(filePath, replacements) {
9999

100100
function getScripts(locale, apiStyle) {
101101
const base = {
102+
"method": "node ./node_modules/apiops-cycles-method-data/packages/create-apiops/bin/method-cli.js",
103+
"method:start": `node ./node_modules/apiops-cycles-method-data/packages/create-apiops/bin/method-cli.js start --locale ${locale}`,
104+
"method:resources:strategy": `node ./node_modules/apiops-cycles-method-data/packages/create-apiops/bin/method-cli.js resources --station api-product-strategy --locale ${locale}`,
105+
"method:canvases:new-api": `node ./node_modules/apiops-cycles-method-data/packages/create-apiops/bin/method-cli.js generate-canvases --preset new-api --style "${apiStyle}" --locale ${locale} --output ./specs/canvases`,
102106
"method:stations": `node ./node_modules/apiops-cycles-method-data/skills/new-api-guide/scripts/get-core-stations.cjs ${locale}`,
103107
"method:resource:audit": `node ./node_modules/apiops-cycles-method-data/skills/new-api-guide/scripts/get-resource-metadata.cjs api-audit-checklist ${locale}`
104108
};
@@ -119,52 +123,6 @@ function getScripts(locale, apiStyle) {
119123
return base;
120124
}
121125

122-
function createStarterCanvas(targetDir, locale = "en", canvasId = "domainCanvas") {
123-
const canvasDataPath = path.join(
124-
targetDir,
125-
"node_modules",
126-
"apiops-cycles-method-data",
127-
"canvasData.json"
128-
);
129-
130-
if (!fs.existsSync(canvasDataPath)) {
131-
return;
132-
}
133-
134-
const canvasData = JSON.parse(fs.readFileSync(canvasDataPath, "utf8"));
135-
const canvas = canvasData[canvasId];
136-
137-
if (!canvas) {
138-
return;
139-
}
140-
141-
const starter = {
142-
templateId: canvasId,
143-
locale,
144-
metadata: {
145-
source: "APIOps Cycles method",
146-
license: "CC-BY-SA 4.0",
147-
authors: ["Project team"],
148-
website: "www.apiopscycles.com",
149-
date: new Date().toISOString()
150-
},
151-
sections: canvas.sections.map((section) => ({
152-
sectionId: section.id,
153-
stickyNotes: [
154-
{
155-
content: "Placeholder",
156-
size: 80,
157-
color: "#FFF399"
158-
}
159-
]
160-
}))
161-
};
162-
163-
const outPath = path.join(targetDir, "specs", "canvases", "example.json");
164-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
165-
fs.writeFileSync(outPath, `${JSON.stringify(starter, null, 2)}\n`);
166-
}
167-
168126
function hasMissingFlagValue(args) {
169127
return ["name", "locale", "style"].some((key) => args[key] === undefined && process.argv.includes(`--${key}`));
170128
}
@@ -223,7 +181,8 @@ async function main() {
223181
const replacements = {
224182
"__PROJECT_NAME__": projectName,
225183
"__LOCALE__": locale,
226-
"__API_TITLE__": projectName.replace(/[-_]/g, " ")
184+
"__API_TITLE__": projectName.replace(/[-_]/g, " "),
185+
"__API_STYLE__": apiStyle
227186
};
228187

229188
replaceInFile(path.join(targetDir, "README.md"), replacements);
@@ -251,15 +210,37 @@ async function main() {
251210
process.exit(result.status || 1);
252211
}
253212

254-
createStarterCanvas(targetDir, locale, "domainCanvas");
213+
const canvasInit = spawnSync(
214+
"node",
215+
[
216+
"./node_modules/apiops-cycles-method-data/packages/create-apiops/bin/method-cli.js",
217+
"generate-canvases",
218+
"--preset", "new-api",
219+
"--style", apiStyle,
220+
"--locale", locale,
221+
"--output", "./specs/canvases"
222+
],
223+
{
224+
cwd: targetDir,
225+
stdio: "inherit",
226+
shell: true
227+
}
228+
);
229+
230+
if (canvasInit.status !== 0) {
231+
console.error("Starter canvas generation failed");
232+
process.exit(canvasInit.status || 1);
233+
}
255234
} else {
256-
console.log("\nStarter canvas was not generated yet.");
257-
console.log("Run `npm install` first, then regenerate it with the scaffolder or a helper command.");
235+
console.log("\nStarter canvases were not generated yet.");
236+
console.log("Run `npm install` first, then `npm run method:canvases:new-api`.");
258237
}
259238

260239
console.log("\nNext steps:");
261240
console.log(` cd ${projectName}`);
262-
console.log(" npm run method:stations");
241+
console.log(" npm run method:start");
242+
console.log(" npm run method:resources:strategy");
243+
console.log(" npm run method:canvases:new-api");
263244
}
264245

265246
main().catch((err) => {

0 commit comments

Comments
 (0)