@jstn-sdk/ma 0.1.2 → 0.1.3

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 CHANGED
@@ -10,9 +10,9 @@
10
10
  </div>
11
11
 
12
12
  > [!IMPORTANT]
13
- > Meta-Architect `v0.1.2` is a production-grade skills line.
13
+ > Meta-Architect `v0.1.3` is a production-grade skills line.
14
14
  > It is not a lightweight demo branch.
15
- > From `v0.1.2` onward, the package is expected to ship with stable skill contracts, deterministic packaging, explicit release gates, and honest install and publish surfaces.
15
+ > From `v0.1.3` onward, the package is expected to ship with stable skill contracts, deterministic packaging, explicit release gates, and honest install and publish surfaces.
16
16
 
17
17
  ## Overview
18
18
 
@@ -44,7 +44,7 @@ It adds:
44
44
  </tr>
45
45
  <tr>
46
46
  <td><strong>Release line</strong></td>
47
- <td><code>v0.1.2</code></td>
47
+ <td><code>v0.1.3</code></td>
48
48
  </tr>
49
49
  <tr>
50
50
  <td><strong>License</strong></td>
@@ -193,7 +193,7 @@ Required output:
193
193
  5. Data model and storage choices
194
194
  6. Auth/security considerations
195
195
  7. DX/UX considerations
196
- 8. Delivery plan for v0.1.2
196
+ 8. Delivery plan for v0.1.3
197
197
  9. Risks and trade-offs
198
198
  10. Decision log
199
199
  11. Exact next trigger to run after this
@@ -517,7 +517,7 @@ Provenance note:
517
517
  | [Plugin README](./plugins/meta-architect/README.md) | plugin distribution surface |
518
518
  | [Collaborative Whiteboard Mission](./missions/collaborative-whiteboard/mission.md) | concrete scenario walkthrough |
519
519
  | [Release Spec](./docs/release-spec.md) | release and gate policy |
520
- | [Release Readiness](./docs/qa/release-readiness-0.1.2.md) | QA evidence for the `v0.1.2` line |
520
+ | [Release Readiness](./docs/qa/release-readiness-0.1.3.md) | QA evidence for the `v0.1.3` line |
521
521
 
522
522
  ## Release Hygiene
523
523
 
package/docs/README.md CHANGED
@@ -17,7 +17,7 @@ Meta-Architect documentation is organized by operator task.
17
17
 
18
18
  ## QA and readiness
19
19
 
20
- - [Release Readiness 0.1.2](./qa/release-readiness-0.1.2.md)
20
+ - [Release Readiness 0.1.3](./qa/release-readiness-0.1.3.md)
21
21
 
22
22
  ## Repo structure references
23
23
 
@@ -74,7 +74,7 @@ Required output:
74
74
  5. Data model and storage choices
75
75
  6. Auth/security considerations
76
76
  7. DX/UX considerations
77
- 8. Delivery plan for v0.1.2
77
+ 8. Delivery plan for v0.1.3
78
78
  9. Risks and trade-offs
79
79
  10. Decision log
80
80
  11. Exact next trigger to run after this
@@ -1,25 +1,25 @@
1
- # Release Readiness 0.1.2
1
+ # Release Readiness 0.1.3
2
2
 
3
3
  ## Production bar
4
4
 
5
- `v0.1.2` is treated as production only when:
5
+ `v0.1.3` is treated as production only when:
6
6
  - the package installs cleanly from the canonical public install command
7
7
  - the Codex-hosted runtime path works end to end
8
8
  - the helper flow remains valid for scripted verification
9
- - release docs, package metadata, and workflows all agree on `0.1.2`
9
+ - release docs, package metadata, and workflows all agree on `0.1.3`
10
10
 
11
11
  Target release state:
12
- - npm package: `@jstn-sdk/ma@0.1.2`
12
+ - npm package: `@jstn-sdk/ma@0.1.3`
13
13
  - npm registry state: pending publish
14
- - publishability note: `0.1.1` is already published, so `0.1.2` is the next publishable package line
15
- - git tag: `v0.1.2`
16
- - GitHub release: pending publish for `v0.1.2`
14
+ - publishability note: `0.1.2` is already published, so `0.1.3` is the next publishable package line
15
+ - git tag: `v0.1.3`
16
+ - GitHub release: pending publish for `v0.1.3`
17
17
 
18
18
  ## Production checklist
19
19
 
20
20
  - skills-first product identity: PASS
21
21
  - package/plugin identity aligned to `@jstn-sdk/ma`: PASS
22
- - version/tag alignment `0.1.2` / `v0.1.2`: PASS
22
+ - version/tag alignment `0.1.3` / `v0.1.3`: PASS
23
23
  - install/uninstall docs aligned: PASS
24
24
  - onboarding is concise and sequential: PASS
25
25
  - helper command documented as secondary: PASS
@@ -1,13 +1,13 @@
1
- # v0.1.2 Requirements & Rules
1
+ # v0.1.3 Requirements & Rules
2
2
 
3
3
  ## Production definition
4
4
 
5
- Meta-Architect `v0.1.2` is production only when:
5
+ Meta-Architect `v0.1.3` is production only when:
6
6
  1. the package/install surface works
7
7
  2. the in-session skill workflow from `$arch` through `$build` works
8
8
  3. the release evidence matches the actual package and git tag
9
9
 
10
- ## What `v0.1.2` must have
10
+ ## What `v0.1.3` must have
11
11
 
12
12
  ### 1. Canonical package/runtime path
13
13
 
@@ -49,11 +49,11 @@ Canonical state files:
49
49
 
50
50
  ### 4. Required release evidence
51
51
 
52
- - `package.json` version `0.1.2`
53
- - git tag `v0.1.2`
52
+ - `package.json` version `0.1.3`
53
+ - git tag `v0.1.3`
54
54
  - `RELEASE.md`
55
55
  - `CHANGELOG.md`
56
- - `docs/qa/release-readiness-0.1.2.md`
56
+ - `docs/qa/release-readiness-0.1.3.md`
57
57
  - green `npm run release:check`
58
58
 
59
59
  ### 5. Dist-tag discipline
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jstn-sdk/ma",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Codex-native skills system for architecture, evidence, review, and gated build guidance.",
5
5
  "license": "MIT",
6
6
  "author": "JustineDevs",
@@ -60,6 +60,7 @@
60
60
  "status": "node ./bin/ma.js status",
61
61
  "build:gate": "node ./bin/ma.js run '$build'",
62
62
  "release:meta": "node ./scripts/release-metadata.js",
63
+ "release:sync": "node ./scripts/release-sync.js",
63
64
  "release:verify": "node ./scripts/release-verify.js",
64
65
  "release:check": "npm run release:verify && npm run skills:manifest && npm run plugin:sync && npm run skills:validate && npm run plugin:verify && npm run skills:pack && npm run check && npm test && npm run pack:inspect",
65
66
  "skills:manifest": "node ./scripts/skills-manifest.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "meta-architect",
3
3
  "displayName": "Meta-Architect",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "description": "Programmatic architecture and verified engineering skills for Codex-native workflows.",
6
6
  "entry": "./README.md",
7
7
  "skillsDir": "./skills"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meta-architect",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Skills-first workflow layer for Codex with architecture, evidence, review, and gated build guidance.",
5
5
  "author": {
6
6
  "name": "JustineDevs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meta-architect",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "collections": [
5
5
  "sindresorhus/awesome",
6
6
  "dzharii/awesome-typescript",
@@ -105,7 +105,7 @@ When consuming the plugin:
105
105
  The plugin version should track the release scope of the core repo.
106
106
 
107
107
  For this repository:
108
- - plugin scope is aligned to Meta-Architect `v0.1.2`
108
+ - plugin scope is aligned to Meta-Architect `v0.1.3`
109
109
  - any breaking contract change should be versioned intentionally
110
110
 
111
111
  The plugin is one distribution surface of the same product, not a separate product line.
@@ -0,0 +1,348 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from "node:child_process";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import process from "node:process";
7
+
8
+ const WATCHED_PREFIXES = [
9
+ "bin/",
10
+ "docs/",
11
+ "example/",
12
+ "mcp/",
13
+ "missions/",
14
+ "plugins/",
15
+ "prompts/",
16
+ ".codex/prompts/",
17
+ "sprint/",
18
+ "templates/",
19
+ "src/",
20
+ "skills/",
21
+ ];
22
+
23
+ const WATCHED_FILES = new Set([
24
+ "README.md",
25
+ "RELEASE.md",
26
+ "CHANGELOG.md",
27
+ "package.json",
28
+ "package-lock.json",
29
+ ]);
30
+
31
+ function parseArgs(argv) {
32
+ const args = {
33
+ bump: "",
34
+ fromRef: "",
35
+ toRef: "",
36
+ githubOutput: "",
37
+ };
38
+
39
+ for (let index = 0; index < argv.length; index += 1) {
40
+ const token = argv[index];
41
+ if (token === "--bump") {
42
+ args.bump = argv[index + 1] ?? "";
43
+ index += 1;
44
+ continue;
45
+ }
46
+ if (token === "--from-ref") {
47
+ args.fromRef = argv[index + 1] ?? "";
48
+ index += 1;
49
+ continue;
50
+ }
51
+ if (token === "--to-ref") {
52
+ args.toRef = argv[index + 1] ?? "";
53
+ index += 1;
54
+ continue;
55
+ }
56
+ if (token === "--github-output") {
57
+ args.githubOutput = argv[index + 1] ?? "";
58
+ index += 1;
59
+ }
60
+ }
61
+
62
+ return args;
63
+ }
64
+
65
+ function readJson(file) {
66
+ return JSON.parse(fs.readFileSync(file, "utf8"));
67
+ }
68
+
69
+ function writeJson(file, value) {
70
+ fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`);
71
+ }
72
+
73
+ function readText(file) {
74
+ return fs.readFileSync(file, "utf8");
75
+ }
76
+
77
+ function writeText(file, content) {
78
+ fs.writeFileSync(file, content);
79
+ }
80
+
81
+ function replaceRequired(text, search, replacement, label) {
82
+ if (!text.includes(search)) {
83
+ throw new Error(`Expected to find ${label}: ${search}`);
84
+ }
85
+ return text.replaceAll(search, replacement);
86
+ }
87
+
88
+ function parseVersion(version) {
89
+ const match = version.match(/^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)$/);
90
+ if (!match?.groups) {
91
+ throw new Error(`Unsupported version for release-sync: ${version}`);
92
+ }
93
+ return {
94
+ major: Number(match.groups.major),
95
+ minor: Number(match.groups.minor),
96
+ patch: Number(match.groups.patch),
97
+ };
98
+ }
99
+
100
+ function bumpVersion(version, bumpKind) {
101
+ const parsed = parseVersion(version);
102
+ if (bumpKind === "major") {
103
+ return `${parsed.major + 1}.0.0`;
104
+ }
105
+ if (bumpKind === "minor") {
106
+ return `${parsed.major}.${parsed.minor + 1}.0`;
107
+ }
108
+ return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
109
+ }
110
+
111
+ function git(args) {
112
+ return execFileSync("git", args, { encoding: "utf8" }).trim();
113
+ }
114
+
115
+ function getChangedFiles({ fromRef, toRef }) {
116
+ if (process.env.RELEASE_SYNC_CHANGED_FILES) {
117
+ return process.env.RELEASE_SYNC_CHANGED_FILES.split("\n")
118
+ .map((line) => line.trim())
119
+ .filter(Boolean);
120
+ }
121
+
122
+ if (fromRef && toRef && !/^0+$/.test(fromRef)) {
123
+ return git(["diff", "--name-only", fromRef, toRef])
124
+ .split("\n")
125
+ .map((line) => line.trim())
126
+ .filter(Boolean);
127
+ }
128
+
129
+ return git(["status", "--porcelain"])
130
+ .split("\n")
131
+ .map((line) => line.slice(3).trim())
132
+ .filter(Boolean);
133
+ }
134
+
135
+ function isWatchedPath(file) {
136
+ return WATCHED_FILES.has(file) || WATCHED_PREFIXES.some((prefix) => file.startsWith(prefix));
137
+ }
138
+
139
+ function prependChangelog(version) {
140
+ const changelogPath = "CHANGELOG.md";
141
+ const changelog = readText(changelogPath);
142
+ if (changelog.includes(`## v${version}`)) {
143
+ return;
144
+ }
145
+
146
+ const next = changelog.replace(
147
+ "# Changelog\n\n",
148
+ `# Changelog\n\n## v${version}\n\n- Release line prepared automatically for v${version}.\n\n`,
149
+ );
150
+ writeText(changelogPath, next);
151
+ }
152
+
153
+ function updateCurrentSurfaceFile(file, oldVersion, nextVersion) {
154
+ const oldTag = `v${oldVersion}`;
155
+ const nextTag = `v${nextVersion}`;
156
+ const oldQa = `release-readiness-${oldVersion}.md`;
157
+ const nextQa = `release-readiness-${nextVersion}.md`;
158
+ let content = readText(file);
159
+ if (content.includes(oldTag)) {
160
+ content = content.replaceAll(oldTag, nextTag);
161
+ }
162
+ if (content.includes(oldVersion)) {
163
+ content = content.replaceAll(oldVersion, nextVersion);
164
+ }
165
+ content = content.replaceAll(oldQa, nextQa);
166
+ writeText(file, content);
167
+ }
168
+
169
+ function syncPackageVersion(nextVersion) {
170
+ const pkg = readJson("package.json");
171
+ const lock = readJson("package-lock.json");
172
+ pkg.version = nextVersion;
173
+ lock.version = nextVersion;
174
+ if (lock.packages?.[""]) {
175
+ lock.packages[""].version = nextVersion;
176
+ }
177
+ writeJson("package.json", pkg);
178
+ writeJson("package-lock.json", lock);
179
+ }
180
+
181
+ function syncPluginVersions(nextVersion) {
182
+ for (const file of [
183
+ path.join("plugins", "meta-architect", ".app.json"),
184
+ path.join("plugins", "meta-architect", ".mcp.json"),
185
+ path.join("plugins", "meta-architect", ".codex-plugin", "plugin.json"),
186
+ ]) {
187
+ const value = readJson(file);
188
+ value.version = nextVersion;
189
+ writeJson(file, value);
190
+ }
191
+ }
192
+
193
+ function syncCurrentReleaseFiles(oldVersion, nextVersion) {
194
+ for (const file of [
195
+ "README.md",
196
+ "RELEASE.md",
197
+ path.join("docs", "README.md"),
198
+ path.join("docs", "getting-started.md"),
199
+ path.join("docs", "release-spec.md"),
200
+ path.join("plugins", "meta-architect", "README.md"),
201
+ ]) {
202
+ updateCurrentSurfaceFile(file, oldVersion, nextVersion);
203
+ }
204
+
205
+ const oldQa = path.join("docs", "qa", `release-readiness-${oldVersion}.md`);
206
+ const nextQa = path.join("docs", "qa", `release-readiness-${nextVersion}.md`);
207
+ fs.renameSync(oldQa, nextQa);
208
+ updateCurrentSurfaceFile(nextQa, oldVersion, nextVersion);
209
+ }
210
+
211
+ function syncSupportingCode(oldVersion, nextVersion) {
212
+ const replacements = [
213
+ {
214
+ file: path.join("src", "skills.js"),
215
+ search: `release-readiness-${oldVersion}.md`,
216
+ replacement: `release-readiness-${nextVersion}.md`,
217
+ label: "skills QA path",
218
+ },
219
+ {
220
+ file: path.join("src", "mcp-live-client.js"),
221
+ search: `version: "${oldVersion}"`,
222
+ replacement: `version: "${nextVersion}"`,
223
+ label: "mcp live client version",
224
+ },
225
+ {
226
+ file: path.join("test", "package-install-smoke.test.js"),
227
+ search: `jstn-sdk-ma-${oldVersion}.tgz`,
228
+ replacement: `jstn-sdk-ma-${nextVersion}.tgz`,
229
+ label: "tarball filename",
230
+ },
231
+ {
232
+ file: path.join("test", "policy.test.js"),
233
+ search: `release/${oldVersion}`,
234
+ replacement: `release/${nextVersion}`,
235
+ label: "release branch example",
236
+ },
237
+ ];
238
+
239
+ for (const entry of replacements) {
240
+ const content = readText(entry.file);
241
+ writeText(entry.file, replaceRequired(content, entry.search, entry.replacement, entry.label));
242
+ }
243
+ }
244
+
245
+ function rewriteReleaseState(nextVersion, previousVersion) {
246
+ const releasePath = "RELEASE.md";
247
+ const qaPath = path.join("docs", "qa", `release-readiness-${nextVersion}.md`);
248
+
249
+ let release = readText(releasePath);
250
+ release = release.replace(
251
+ /- npm package: `@jstn-sdk\/ma@[0-9]+\.[0-9]+\.[0-9]+`/,
252
+ `- npm package: \`@jstn-sdk/ma@${nextVersion}\``,
253
+ );
254
+ release = release.replace(
255
+ /- publishability note: .+/,
256
+ `- publishability note: \`${previousVersion}\` is already published, so \`${nextVersion}\` is the next publishable package line`,
257
+ );
258
+ release = release.replace(
259
+ /- GitHub release: .+/,
260
+ `- GitHub release: pending publish for \`v${nextVersion}\``,
261
+ );
262
+ release = release.replace(
263
+ /- npm publication has not been run yet for `@jstn-sdk\/ma@[0-9]+\.[0-9]+\.[0-9]+`/,
264
+ `- npm publication has not been run yet for \`@jstn-sdk/ma@${nextVersion}\``,
265
+ );
266
+ writeText(releasePath, release);
267
+
268
+ let qa = readText(qaPath);
269
+ qa = qa.replace(
270
+ /- npm package: `@jstn-sdk\/ma@[0-9]+\.[0-9]+\.[0-9]+`/,
271
+ `- npm package: \`@jstn-sdk/ma@${nextVersion}\``,
272
+ );
273
+ qa = qa.replace(
274
+ /- publishability note: .+/,
275
+ `- publishability note: \`${previousVersion}\` is already published, so \`${nextVersion}\` is the next publishable package line`,
276
+ );
277
+ qa = qa.replace(
278
+ /- GitHub release: .+/,
279
+ `- GitHub release: pending publish for \`v${nextVersion}\``,
280
+ );
281
+ writeText(qaPath, qa);
282
+ }
283
+
284
+ function writeGithubOutput(outputPath, { updated, version }) {
285
+ const lines = [`updated=${updated}`, `version=${version}`];
286
+ fs.appendFileSync(outputPath, `${lines.join("\n")}\n`);
287
+ }
288
+
289
+ function main() {
290
+ const args = parseArgs(process.argv.slice(2));
291
+ const pkg = readJson("package.json");
292
+ const currentVersion = pkg.version;
293
+ const changedFiles = getChangedFiles(args);
294
+ const relevantChanges = changedFiles.filter(isWatchedPath);
295
+
296
+ if (relevantChanges.length === 0) {
297
+ if (args.githubOutput) {
298
+ writeGithubOutput(args.githubOutput, { updated: "false", version: currentVersion });
299
+ }
300
+ console.log(
301
+ JSON.stringify(
302
+ {
303
+ updated: false,
304
+ version: currentVersion,
305
+ changedFiles,
306
+ },
307
+ null,
308
+ 2,
309
+ ),
310
+ );
311
+ return;
312
+ }
313
+
314
+ const bumpKind = args.bump || "patch";
315
+ const nextVersion = bumpVersion(currentVersion, bumpKind);
316
+
317
+ syncPackageVersion(nextVersion);
318
+ syncPluginVersions(nextVersion);
319
+ prependChangelog(nextVersion);
320
+ syncCurrentReleaseFiles(currentVersion, nextVersion);
321
+ syncSupportingCode(currentVersion, nextVersion);
322
+ rewriteReleaseState(nextVersion, currentVersion);
323
+
324
+ if (args.githubOutput) {
325
+ writeGithubOutput(args.githubOutput, { updated: "true", version: nextVersion });
326
+ }
327
+
328
+ console.log(
329
+ JSON.stringify(
330
+ {
331
+ updated: true,
332
+ bump: bumpKind,
333
+ previousVersion: currentVersion,
334
+ version: nextVersion,
335
+ changedFiles: relevantChanges,
336
+ },
337
+ null,
338
+ 2,
339
+ ),
340
+ );
341
+ }
342
+
343
+ try {
344
+ main();
345
+ } catch (error) {
346
+ console.error(error.message);
347
+ process.exitCode = 1;
348
+ }
@@ -38,7 +38,7 @@ export class McpSseClient {
38
38
  capabilities: {},
39
39
  clientInfo: {
40
40
  name: "meta-architect",
41
- version: "0.1.2",
41
+ version: "0.1.3",
42
42
  },
43
43
  });
44
44
 
package/src/skills.js CHANGED
@@ -344,8 +344,8 @@ export async function runInit() {
344
344
  path.join(getRepoRoot(), "docs", "release-spec.md"),
345
345
  ],
346
346
  [
347
- path.join(packageRoot, "docs", "qa", "release-readiness-0.1.2.md"),
348
- path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.2.md"),
347
+ path.join(packageRoot, "docs", "qa", "release-readiness-0.1.3.md"),
348
+ path.join(getRepoRoot(), "docs", "qa", "release-readiness-0.1.3.md"),
349
349
  ],
350
350
  ];
351
351