@ai-plugin-marketplace/core 0.2.0 → 0.3.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/dist/core.d.ts CHANGED
@@ -287,6 +287,13 @@ export declare interface InitOptions {
287
287
  * directory.
288
288
  */
289
289
  name?: string;
290
+ /**
291
+ * Version of `@ai-plugin-marketplace/cli` to pin the generated `package.json`'s `cli`
292
+ * dev dependency to (as `^<cliVersion>`). The cli entrypoint supplies its own version here; cli
293
+ * and core ship independently and may differ (e.g. `cli 0.1.1` ships with `core 0.2.0`). When
294
+ * omitted, falls back to core's own version (the historical lockstep assumption).
295
+ */
296
+ cliVersion?: string;
290
297
  }
291
298
 
292
299
  /**
@@ -332,6 +339,50 @@ export declare interface MigrateResult {
332
339
  filesChanged: string[];
333
340
  }
334
341
 
342
+ /**
343
+ * Options for {@link refreshScaffold}.
344
+ *
345
+ * @public
346
+ */
347
+ export declare interface RefreshOptions {
348
+ /**
349
+ * Overwrite toolkit-owned scaffold files even when their on-disk content has diverged from what
350
+ * the toolkit last wrote (i.e. the user edited them). Without this, diverged files are reported
351
+ * as conflicts and left untouched.
352
+ */
353
+ force?: boolean;
354
+ }
355
+
356
+ /**
357
+ * Per-file outcome of a {@link refreshScaffold} run. Returned (one per managed scaffold file) so
358
+ * the CLI can report what changed without re-deriving it.
359
+ *
360
+ * @public
361
+ */
362
+ export declare interface RefreshOutcome {
363
+ /** Repo-relative POSIX path of the managed scaffold file. */
364
+ path: string;
365
+ /**
366
+ * - `updated` — content changed and was rewritten (file was pristine or `--force`).
367
+ * - `unchanged` — already matched the current render; nothing written.
368
+ * - `recreated` — file was missing and was written from the render.
369
+ * - `conflict` — on-disk content diverged from the recorded hash; left untouched (no `--force`).
370
+ * - `overwritten` — diverged but rewritten because `--force` was set.
371
+ */
372
+ status: 'updated' | 'unchanged' | 'recreated' | 'conflict' | 'overwritten';
373
+ }
374
+
375
+ /**
376
+ * Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
377
+ * repo at `targetDir` to match the installed tooling — the upgrade path after
378
+ * `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
379
+ * user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
380
+ * Returns one outcome per managed file; never rejects on conflict.
381
+ *
382
+ * @public
383
+ */
384
+ export declare function refreshScaffold(targetDir: string, opts?: RefreshOptions): Promise<RefreshOutcome[]>;
385
+
335
386
  /**
336
387
  * Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
337
388
  * default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
package/dist/index.d.ts CHANGED
@@ -10,6 +10,6 @@
10
10
  */
11
11
  export { defineConfig, defineRepoConfig, defineWorkspace } from './config.js';
12
12
  export type { AipmConfig, AipmConfigInput, AipmRepoConfig, AipmRepoConfigInput, AipmWorkspace, AipmWorkspaceInput, } from './config.js';
13
- export { build, validate, scaffold, init, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
14
- export type { TargetId, BuildOptions, BuildResult, GeneratedFile, ValidateOptions, ValidationResult, Finding, FindingCode, ScaffoldOptions, InitOptions, MigrateOptions, MigrateResult, SupportReport, } from './pipeline/types.js';
13
+ export { build, validate, scaffold, init, refreshScaffold, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
14
+ export type { TargetId, BuildOptions, BuildResult, GeneratedFile, ValidateOptions, ValidationResult, Finding, FindingCode, ScaffoldOptions, InitOptions, RefreshOptions, RefreshOutcome, MigrateOptions, MigrateResult, SupportReport, } from './pipeline/types.js';
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -9,5 +9,5 @@
9
9
  * @packageDocumentation
10
10
  */
11
11
  export { defineConfig, defineRepoConfig, defineWorkspace } from './config.js';
12
- export { build, validate, scaffold, init, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
12
+ export { build, validate, scaffold, init, refreshScaffold, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
13
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9E,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9E,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
@@ -21,13 +21,24 @@ export interface InitFile {
21
21
  /** Full file contents, including a trailing newline. */
22
22
  content: string;
23
23
  }
24
+ /**
25
+ * Toolkit-owned **scaffold** files that `aipm init --refresh` keeps in sync with the installed
26
+ * tooling: the CI workflow and `.gitignore`. These are pure tooling recipes — their content is
27
+ * independent of the repo name and the pinned toolkit version, so refresh can re-render them with
28
+ * no inputs and compare byte-for-byte. (Files with repo identity or user content — `package.json`,
29
+ * `aipm.workspace.ts`, `README.md`, plugins, `aipm build` output — are deliberately NOT here.)
30
+ *
31
+ * Output is deterministic and stably ordered.
32
+ */
33
+ export declare function buildManagedScaffoldFiles(): InitFile[];
24
34
  /**
25
35
  * Build the complete, deterministic seed file set for a consumer repo named `name`, pinning the
26
- * `@ai-plugin-marketplace/cli` dev dependency to `^${toolkitVersion}`.
36
+ * `cli`/`core` dev dependencies to carets of `cliVersion`/`coreVersion` respectively.
27
37
  *
28
- * The set mirrors §3.2: `package.json`, `.gitignore`, `README.md`, both repo-root marketplace
29
- * registries, an empty `plugins/` (seeded with `.gitkeep` so the directory is tracked), and the
30
- * CI workflow. Output is a pure function of the two inputs stable ordering, no timestamps.
38
+ * The set mirrors §3.2: `package.json`, the {@link buildManagedScaffoldFiles managed scaffold
39
+ * files} (`.gitignore`, CI workflow), `README.md`, both repo-root marketplace registries, and an
40
+ * empty `plugins/` (seeded with `.gitkeep` so the directory is tracked). Output is a pure function
41
+ * of the inputs — stable ordering, no timestamps.
31
42
  */
32
- export declare function buildInitFiles(name: string, toolkitVersion: string): InitFile[];
43
+ export declare function buildInitFiles(name: string, cliVersion: string, coreVersion: string): InitFile[];
33
44
  //# sourceMappingURL=init-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,gGAAgG;AAChG,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;CACjB;AA8GD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,QAAQ,EAAE,CAU/E"}
1
+ {"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,gGAAgG;AAChG,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;CACjB;AAqID;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,IAAI,QAAQ,EAAE,CAKtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE,CAShG"}
@@ -17,33 +17,40 @@
17
17
  const json = String.raw;
18
18
  const md = String.raw;
19
19
  const yaml = String.raw;
20
+ /**
21
+ * pnpm version pinned in the generated `package.json#packageManager`. The CI workflow reads the
22
+ * pnpm version from this field (it runs `pnpm/action-setup` without a hard-coded version), so the
23
+ * two stay in sync. Bumped deliberately when the recommended pnpm baseline moves.
24
+ */
25
+ const PACKAGE_MANAGER = 'pnpm@10.30.3';
20
26
  /**
21
27
  * The `package.json` for a generated consumer repo.
22
28
  *
23
29
  * - `private: true` — a plugin repo is never published to npm; only its plugins ship to registries.
24
30
  * - `type: 'module'` — the toolkit is ESM-only (§8.1), and `aipm.config.ts` files are ESM.
31
+ * - `packageManager` pins pnpm; the CI workflow reads the pnpm version from here.
25
32
  * - `scripts` call `aipm` directly (it is on PATH via the dev dependency's bin).
26
- * - The `@ai-plugin-marketplace/cli` dev dependency is pinned to `^<toolkitVersion>` so authors
27
- * upgrade the whole toolkit in lockstep via `pnpm up` (§9.1 lockstep release, §11 contract).
33
+ * - `cli` provides the `aipm` binary; `core` provides `defineConfig`/`defineWorkspace` for each
34
+ * plugin's `aipm.config.ts` (§6.1). They ship independently and may differ (`cli 0.1.1` ships
35
+ * with `core 0.2.0`), so each is pinned to a caret of its own version; authors upgrade both via
36
+ * `pnpm up` (§11 contract).
28
37
  *
29
38
  * Emitted as 2-space JSON with a trailing newline to match the repo's formatting conventions.
30
39
  */
31
- function renderPackageJson(name, toolkitVersion) {
40
+ function renderPackageJson(name, cliVersion, coreVersion) {
32
41
  const pkg = {
33
42
  name,
34
43
  private: true,
35
44
  type: 'module',
45
+ packageManager: PACKAGE_MANAGER,
36
46
  scripts: {
37
47
  build: 'aipm build',
38
48
  check: 'aipm validate',
39
49
  scaffold: 'aipm scaffold',
40
50
  },
41
51
  devDependencies: {
42
- // cli provides the `aipm` binary; core provides `defineConfig` for each
43
- // plugin's `aipm.config.ts` import (§6.1). Both pinned to the same toolkit
44
- // version and upgraded together via `pnpm up`.
45
- '@ai-plugin-marketplace/cli': `^${toolkitVersion}`,
46
- '@ai-plugin-marketplace/core': `^${toolkitVersion}`,
52
+ '@ai-plugin-marketplace/cli': `^${cliVersion}`,
53
+ '@ai-plugin-marketplace/core': `^${coreVersion}`,
47
54
  },
48
55
  };
49
56
  return `${JSON.stringify(pkg, null, 2)}\n`;
@@ -95,21 +102,43 @@ function renderCiWorkflow() {
95
102
 
96
103
  on:
97
104
  push:
105
+ branches: [main]
98
106
  pull_request:
107
+ branches: [main]
99
108
 
100
109
  jobs:
101
- build-and-validate:
110
+ CI:
102
111
  runs-on: ubuntu-latest
112
+ env:
113
+ CI: "true"
103
114
  steps:
104
115
  - uses: actions/checkout@v4
116
+
105
117
  - uses: pnpm/action-setup@v4
118
+ # version is read from package.json#packageManager — do not duplicate here
119
+
106
120
  - uses: actions/setup-node@v4
107
121
  with:
108
- node-version: 20
122
+ node-version: 24
109
123
  cache: pnpm
110
- - run: pnpm install --frozen-lockfile
111
- - run: pnpm exec aipm build
112
- - run: pnpm exec aipm validate
124
+
125
+ - name: Install dependencies
126
+ run: pnpm install --frozen-lockfile
127
+
128
+ - name: Build plugins
129
+ run: pnpm exec aipm build
130
+
131
+ - name: Verify the tree is clean after build (freshness)
132
+ run: |
133
+ if [ -n "$(git status --porcelain)" ]; then
134
+ echo "::error::Working tree is dirty after 'aipm build'. Run 'aipm build' locally and commit the regenerated artifacts."
135
+ git status --porcelain
136
+ git --no-pager diff
137
+ exit 1
138
+ fi
139
+
140
+ - name: Validate plugins
141
+ run: pnpm exec aipm validate
113
142
  `;
114
143
  }
115
144
  /** `.gitignore` for a consumer repo: dependencies, build intermediates, OS/local cruft. */
@@ -121,22 +150,37 @@ function renderGitignore() {
121
150
  `;
122
151
  }
123
152
  /**
124
- * Build the complete, deterministic seed file set for a consumer repo named `name`, pinning the
125
- * `@ai-plugin-marketplace/cli` dev dependency to `^${toolkitVersion}`.
153
+ * Toolkit-owned **scaffold** files that `aipm init --refresh` keeps in sync with the installed
154
+ * tooling: the CI workflow and `.gitignore`. These are pure tooling recipes — their content is
155
+ * independent of the repo name and the pinned toolkit version, so refresh can re-render them with
156
+ * no inputs and compare byte-for-byte. (Files with repo identity or user content — `package.json`,
157
+ * `aipm.workspace.ts`, `README.md`, plugins, `aipm build` output — are deliberately NOT here.)
126
158
  *
127
- * The set mirrors §3.2: `package.json`, `.gitignore`, `README.md`, both repo-root marketplace
128
- * registries, an empty `plugins/` (seeded with `.gitkeep` so the directory is tracked), and the
129
- * CI workflow. Output is a pure function of the two inputs — stable ordering, no timestamps.
159
+ * Output is deterministic and stably ordered.
130
160
  */
131
- export function buildInitFiles(name, toolkitVersion) {
161
+ export function buildManagedScaffoldFiles() {
132
162
  return [
133
- { path: 'package.json', content: renderPackageJson(name, toolkitVersion) },
134
163
  { path: '.gitignore', content: renderGitignore() },
164
+ { path: '.github/workflows/ci.yml', content: renderCiWorkflow() },
165
+ ];
166
+ }
167
+ /**
168
+ * Build the complete, deterministic seed file set for a consumer repo named `name`, pinning the
169
+ * `cli`/`core` dev dependencies to carets of `cliVersion`/`coreVersion` respectively.
170
+ *
171
+ * The set mirrors §3.2: `package.json`, the {@link buildManagedScaffoldFiles managed scaffold
172
+ * files} (`.gitignore`, CI workflow), `README.md`, both repo-root marketplace registries, and an
173
+ * empty `plugins/` (seeded with `.gitkeep` so the directory is tracked). Output is a pure function
174
+ * of the inputs — stable ordering, no timestamps.
175
+ */
176
+ export function buildInitFiles(name, cliVersion, coreVersion) {
177
+ return [
178
+ { path: 'package.json', content: renderPackageJson(name, cliVersion, coreVersion) },
135
179
  { path: 'README.md', content: renderReadme(name) },
136
180
  { path: '.claude-plugin/marketplace.json', content: renderEmptyMarketplace() },
137
181
  { path: '.cursor-plugin/marketplace.json', content: renderEmptyMarketplace() },
138
182
  { path: 'plugins/.gitkeep', content: '' },
139
- { path: '.github/workflows/ci.yml', content: renderCiWorkflow() },
183
+ ...buildManagedScaffoldFiles(),
140
184
  ];
141
185
  }
142
186
  //# sourceMappingURL=init-template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AACxB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;AACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AAUxB;;;;;;;;;;GAUG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,cAAsB;IAC7D,MAAM,GAAG,GAAG;QACV,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,eAAe;YACtB,QAAQ,EAAE,eAAe;SAC1B;QACD,eAAe,EAAE;YACf,wEAAwE;YACxE,2EAA2E;YAC3E,+CAA+C;YAC/C,4BAA4B,EAAE,IAAI,cAAc,EAAE;YAClD,6BAA6B,EAAE,IAAI,cAAc,EAAE;SACpD;KACF,CAAC;IACF,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB;IAC7B,OAAO,IAAI,CAAA;;;CAGZ,CAAC;AACF,CAAC;AAED,2EAA2E;AAC3E,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,EAAE,CAAA,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;CAwBnB,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAA;;;;;;;;;;;;;;;;;;;CAmBZ,CAAC;AACF,CAAC;AAED,2FAA2F;AAC3F,SAAS,eAAe;IACtB,OAAO;;;;CAIR,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,cAAsB;IACjE,OAAO;QACL,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE;QAC1E,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAClD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE;QAClD,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE;KAClE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AACxB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;AACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AAExB;;;;GAIG;AACH,MAAM,eAAe,GAAG,cAAc,CAAC;AAUvC;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,UAAkB,EAAE,WAAmB;IAC9E,MAAM,GAAG,GAAG;QACV,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;QACd,cAAc,EAAE,eAAe;QAC/B,OAAO,EAAE;YACP,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,eAAe;YACtB,QAAQ,EAAE,eAAe;SAC1B;QACD,eAAe,EAAE;YACf,4BAA4B,EAAE,IAAI,UAAU,EAAE;YAC9C,6BAA6B,EAAE,IAAI,WAAW,EAAE;SACjD;KACF,CAAC;IACF,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB;IAC7B,OAAO,IAAI,CAAA;;;CAGZ,CAAC;AACF,CAAC;AAED,2EAA2E;AAC3E,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,EAAE,CAAA,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;CAwBnB,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCZ,CAAC;AACF,CAAC;AAED,2FAA2F;AAC3F,SAAS,eAAe;IACtB,OAAO;;;;CAIR,CAAC;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAClD,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE;KAClE,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,UAAkB,EAAE,WAAmB;IAClF,OAAO;QACL,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE;QACnF,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE;QAClD,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,GAAG,yBAAyB,EAAE;KAC/B,CAAC;AACJ,CAAC"}
@@ -4,35 +4,38 @@
4
4
  *
5
5
  * This is the filesystem-writing orchestrator behind the public `init` operation and the
6
6
  * `aipm init [dir]` CLI surface. The generated file *contents* live in `init-template.ts`; this
7
- * module is the I/O boundary: it resolves the toolkit version to pin, refuses to clobber a
8
- * non-empty target, and writes the seed tree.
7
+ * module is the I/O boundary: it resolves the versions to pin, refuses to clobber a non-empty
8
+ * target, writes the seed tree, and seeds the `.aipm/scaffold.json` refresh sidecar.
9
9
  *
10
- * **Version pinning (§9.1 lockstep release).** core and cli ship in lockstep, so the `cli` dev
11
- * dependency is pinned to a caret of core's *own* version — read at runtime from this package's
12
- * `package.json`, resolved relative to {@link import.meta.url} exactly as `load-config.ts` resolves
13
- * the package entrypoint. Today that yields `^0.1.0-alpha.0`; once 0.1.0 ships, an `init` run from
14
- * the published cli pins `^0.1.0`.
10
+ * **Version pinning.** `cli` and `core` ship independently and may differ (e.g. `cli 0.1.1` ships
11
+ * with `core 0.2.0`), so the generated `package.json` pins each to a caret of its *own* version.
12
+ * `core`'s version is read at runtime from this package's `package.json` (resolved relative to
13
+ * {@link import.meta.url}, exactly as `load-config.ts` resolves the package entrypoint); `cli`'s
14
+ * version is supplied by the cli entrypoint via {@link InitOptions.cliVersion} (it reads its own
15
+ * `package.json`). When `cliVersion` is omitted, it falls back to core's version.
15
16
  *
16
17
  * @see docs/specs/architecture.md §3.2 (template repo contents)
17
- * @see docs/specs/architecture.md §9.1 (lockstep release lines)
18
18
  * @see docs/specs/architecture.md §11 (template→toolkit dependency contract)
19
+ * @see docs/specs/scaffold-refresh-and-upgrade.md (`aipm init --refresh`)
19
20
  */
20
21
  import type { InitOptions } from './types.js';
21
22
  /**
22
23
  * Scaffold a thin consumer repo at `targetDir` (§3.2).
23
24
  *
24
- * Writes `package.json` (with the `@ai-plugin-marketplace/cli` dev dependency pinned to a caret of
25
- * the current toolkit version), `.gitignore`, `README.md`, both repo-root marketplace registries
26
- * (`{ "plugins": [] }`), an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs
27
- * `aipm build` then `aipm validate` (§10.5 freshness). The repo name defaults to
28
- * `basename(targetDir)`; override it with `opts.name`.
25
+ * Writes `package.json` (with `cli`/`core` dev dependencies pinned to carets of their respective
26
+ * versions), `.gitignore`, `README.md`, both repo-root marketplace registries (`{ "plugins": [] }`),
27
+ * an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs `aipm build` then
28
+ * `aipm validate` (§10.5 freshness). It also seeds `.aipm/scaffold.json` so a later
29
+ * `aipm init --refresh` can tell pristine toolkit-owned files from user edits. The repo name
30
+ * defaults to `basename(targetDir)`; override it with `opts.name`.
29
31
  *
30
32
  * **Refuses to clobber.** If `targetDir` exists and is a non-empty directory (or exists as a
31
33
  * non-directory), the function throws and writes nothing. Creating into a fresh or empty directory
32
34
  * is fine.
33
35
  *
34
36
  * @param targetDir - Absolute or relative path to the directory to scaffold into.
35
- * @param opts - Init options; `name` overrides the derived repo name.
37
+ * @param opts - Init options; `name` overrides the derived repo name, `cliVersion` the pinned cli
38
+ * dependency version (defaults to core's version).
36
39
  * @throws {Error} When `targetDir` exists and is non-empty (or is not a directory).
37
40
  */
38
41
  export declare function runInit(targetDir: string, opts?: InitOptions): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA6B9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBtF"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA6B9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BtF"}
@@ -4,23 +4,25 @@
4
4
  *
5
5
  * This is the filesystem-writing orchestrator behind the public `init` operation and the
6
6
  * `aipm init [dir]` CLI surface. The generated file *contents* live in `init-template.ts`; this
7
- * module is the I/O boundary: it resolves the toolkit version to pin, refuses to clobber a
8
- * non-empty target, and writes the seed tree.
7
+ * module is the I/O boundary: it resolves the versions to pin, refuses to clobber a non-empty
8
+ * target, writes the seed tree, and seeds the `.aipm/scaffold.json` refresh sidecar.
9
9
  *
10
- * **Version pinning (§9.1 lockstep release).** core and cli ship in lockstep, so the `cli` dev
11
- * dependency is pinned to a caret of core's *own* version — read at runtime from this package's
12
- * `package.json`, resolved relative to {@link import.meta.url} exactly as `load-config.ts` resolves
13
- * the package entrypoint. Today that yields `^0.1.0-alpha.0`; once 0.1.0 ships, an `init` run from
14
- * the published cli pins `^0.1.0`.
10
+ * **Version pinning.** `cli` and `core` ship independently and may differ (e.g. `cli 0.1.1` ships
11
+ * with `core 0.2.0`), so the generated `package.json` pins each to a caret of its *own* version.
12
+ * `core`'s version is read at runtime from this package's `package.json` (resolved relative to
13
+ * {@link import.meta.url}, exactly as `load-config.ts` resolves the package entrypoint); `cli`'s
14
+ * version is supplied by the cli entrypoint via {@link InitOptions.cliVersion} (it reads its own
15
+ * `package.json`). When `cliVersion` is omitted, it falls back to core's version.
15
16
  *
16
17
  * @see docs/specs/architecture.md §3.2 (template repo contents)
17
- * @see docs/specs/architecture.md §9.1 (lockstep release lines)
18
18
  * @see docs/specs/architecture.md §11 (template→toolkit dependency contract)
19
+ * @see docs/specs/scaffold-refresh-and-upgrade.md (`aipm init --refresh`)
19
20
  */
20
21
  import * as fs from 'node:fs';
21
22
  import * as path from 'node:path';
22
23
  import { fileURLToPath } from 'node:url';
23
24
  import { buildInitFiles } from './init-template.js';
25
+ import { writeScaffoldSidecar } from './scaffold-refresh.js';
24
26
  /**
25
27
  * Read this package's `package.json#version`, resolved relative to this module's location.
26
28
  *
@@ -51,18 +53,20 @@ function isFreshTarget(dir) {
51
53
  /**
52
54
  * Scaffold a thin consumer repo at `targetDir` (§3.2).
53
55
  *
54
- * Writes `package.json` (with the `@ai-plugin-marketplace/cli` dev dependency pinned to a caret of
55
- * the current toolkit version), `.gitignore`, `README.md`, both repo-root marketplace registries
56
- * (`{ "plugins": [] }`), an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs
57
- * `aipm build` then `aipm validate` (§10.5 freshness). The repo name defaults to
58
- * `basename(targetDir)`; override it with `opts.name`.
56
+ * Writes `package.json` (with `cli`/`core` dev dependencies pinned to carets of their respective
57
+ * versions), `.gitignore`, `README.md`, both repo-root marketplace registries (`{ "plugins": [] }`),
58
+ * an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs `aipm build` then
59
+ * `aipm validate` (§10.5 freshness). It also seeds `.aipm/scaffold.json` so a later
60
+ * `aipm init --refresh` can tell pristine toolkit-owned files from user edits. The repo name
61
+ * defaults to `basename(targetDir)`; override it with `opts.name`.
59
62
  *
60
63
  * **Refuses to clobber.** If `targetDir` exists and is a non-empty directory (or exists as a
61
64
  * non-directory), the function throws and writes nothing. Creating into a fresh or empty directory
62
65
  * is fine.
63
66
  *
64
67
  * @param targetDir - Absolute or relative path to the directory to scaffold into.
65
- * @param opts - Init options; `name` overrides the derived repo name.
68
+ * @param opts - Init options; `name` overrides the derived repo name, `cliVersion` the pinned cli
69
+ * dependency version (defaults to core's version).
66
70
  * @throws {Error} When `targetDir` exists and is non-empty (or is not a directory).
67
71
  */
68
72
  export async function runInit(targetDir, opts = {}) {
@@ -72,13 +76,17 @@ export async function runInit(targetDir, opts = {}) {
72
76
  'Choose a new path or an empty directory.');
73
77
  }
74
78
  const name = opts.name ?? path.basename(resolved);
75
- const files = buildInitFiles(name, coreVersion());
79
+ const core = coreVersion();
80
+ const cli = opts.cliVersion ?? core;
81
+ const files = buildInitFiles(name, cli, core);
76
82
  fs.mkdirSync(resolved, { recursive: true });
77
83
  for (const file of files) {
78
84
  const full = path.join(resolved, file.path);
79
85
  fs.mkdirSync(path.dirname(full), { recursive: true });
80
86
  fs.writeFileSync(full, file.content, 'utf-8');
81
87
  }
88
+ // Seed the refresh sidecar so `aipm init --refresh` has a baseline of toolkit-owned content.
89
+ writeScaffoldSidecar(resolved);
82
90
  return Promise.resolve();
83
91
  }
84
92
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD;;;;;;;GAOG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,sFAAsF;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;IACjF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAoB,EAAE;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,oDAAoD;YACxF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAElD,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;;;;;GAOG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,sFAAsF;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;IACjF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAoB,EAAE;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,oDAAoD;YACxF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;IACpC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAE9C,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,6FAA6F;IAC7F,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @see docs/specs/architecture.md §8.1
11
11
  */
12
- import type { BuildOptions, BuildResult, InitOptions, MigrateOptions, MigrateResult, ScaffoldOptions, SupportReport, TargetId, ValidateOptions, ValidationResult } from './types.js';
12
+ import type { BuildOptions, BuildResult, InitOptions, MigrateOptions, MigrateResult, RefreshOptions, RefreshOutcome, ScaffoldOptions, SupportReport, TargetId, ValidateOptions, ValidationResult } from './types.js';
13
13
  /**
14
14
  * Build a single plugin or every plugin under a repo root. `path` may be a plugin directory
15
15
  * (contains `aipm.config.ts`) or a repo root (contains `plugins/`); the orchestrator detects
@@ -34,6 +34,16 @@ export declare function validate(targetPath: string, opts?: ValidateOptions): Pr
34
34
  * @public
35
35
  */
36
36
  export declare function init(targetDir: string, opts?: InitOptions): Promise<void>;
37
+ /**
38
+ * Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
39
+ * repo at `targetDir` to match the installed tooling — the upgrade path after
40
+ * `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
41
+ * user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
42
+ * Returns one outcome per managed file; never rejects on conflict.
43
+ *
44
+ * @public
45
+ */
46
+ export declare function refreshScaffold(targetDir: string, opts?: RefreshOptions): Promise<RefreshOutcome[]>;
37
47
  /**
38
48
  * Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
39
49
  * default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
@@ -1 +1 @@
1
- {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,QAAQ,EACR,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtF;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAMrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,SAAS,QAAQ,EAAE,CAEjD"}
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACb,QAAQ,EACR,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,EAAE,CAAC,CAK3B;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtF;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAMrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,SAAS,QAAQ,EAAE,CAEjD"}
@@ -13,6 +13,7 @@ import * as path from 'node:path';
13
13
  import { runBuild } from './build.js';
14
14
  import { runInit } from './init.js';
15
15
  import { loadRepoConfig } from './load-config.js';
16
+ import { runRefreshScaffold } from './scaffold-refresh.js';
16
17
  import { runScaffold, runAddTarget, runCheckSupport } from './scaffold.js';
17
18
  import { TARGET_IDS } from './types.js';
18
19
  import { runValidate } from './validate.js';
@@ -50,6 +51,21 @@ export function validate(targetPath, opts) {
50
51
  export function init(targetDir, opts) {
51
52
  return runInit(targetDir, opts);
52
53
  }
54
+ /**
55
+ * Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
56
+ * repo at `targetDir` to match the installed tooling — the upgrade path after
57
+ * `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
58
+ * user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
59
+ * Returns one outcome per managed file; never rejects on conflict.
60
+ *
61
+ * @public
62
+ */
63
+ export function refreshScaffold(targetDir, opts) {
64
+ // Defer into the microtask queue so a synchronous failure in the orchestrator (e.g. an I/O error)
65
+ // surfaces as a rejected promise — matching `refreshScaffold(...).catch(...)` expectations —
66
+ // rather than throwing from this call before the promise exists.
67
+ return Promise.resolve().then(() => runRefreshScaffold(targetDir, opts));
68
+ }
53
69
  /**
54
70
  * Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
55
71
  * default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
@@ -1 +1 @@
1
- {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAc5C,sGAAsG;AACtG,SAAS,IAAI;IACX,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,UAAkB,EAAE,IAAmB;IAC3D,OAAO,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAkB,EAAE,IAAsB;IACjE,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,SAAiB,EAAE,IAAkB;IACxD,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,KAAsB;IAC3D,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,sBAAsB;QAC9B,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAgB;IAC3D,OAAO,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAgB5C,sGAAsG;AACtG,SAAS,IAAI;IACX,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,UAAkB,EAAE,IAAmB;IAC3D,OAAO,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAkB,EAAE,IAAsB;IACjE,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,SAAiB,EAAE,IAAkB;IACxD,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,IAAqB;IAErB,kGAAkG;IAClG,6FAA6F;IAC7F,iEAAiE;IACjE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,KAAsB;IAC3D,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,sBAAsB;QAC9B,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAgB;IAC3D,OAAO,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * `aipm init --refresh` — keep a marketplace repo's **toolkit-owned scaffold files** (the CI
3
+ * workflow and `.gitignore`) in sync with the installed tooling, and serve as the upgrade path for
4
+ * any marketplace repo after `pnpm up @ai-plugin-marketplace/*`.
5
+ *
6
+ * Safety rests on a content-hash sidecar at `.aipm/scaffold.json` (mirroring the root-emission
7
+ * sidecar `.aipm/generated-root.json`): it records a hash of the exact content the toolkit last
8
+ * wrote each managed file. Refresh updates a file only when it is still pristine (matches the
9
+ * recorded hash) or missing; a file the user has edited surfaces as a reported conflict and is left
10
+ * untouched unless `--force` is given. A repo with no sidecar entry bootstraps: an already-in-sync
11
+ * file is adopted silently, a diverged one is a conflict to review.
12
+ *
13
+ * The managed set is deliberately narrow — only the pure tooling-recipe files (see
14
+ * {@link buildManagedScaffoldFiles}). `package.json` (deps are `pnpm up`'s job), `aipm.workspace.ts`
15
+ * (repo identity), `README.md` (authored), plugins, and `aipm build` output are never touched.
16
+ *
17
+ * @see docs/specs/scaffold-refresh-and-upgrade.md
18
+ */
19
+ import type { RefreshOptions, RefreshOutcome } from './types.js';
20
+ /** A recorded `{ path, hash }` pair: the hash of the content the toolkit last wrote at `path`. */
21
+ interface SidecarEntry {
22
+ path: string;
23
+ hash: string;
24
+ }
25
+ /** Content hash recorded in the sidecar. `sha256-`-prefixed hex over the UTF-8 bytes. */
26
+ export declare function hashScaffoldContent(content: string): string;
27
+ /**
28
+ * Serialize a sidecar payload: `{ version, files }` with `files` sorted by path for determinism,
29
+ * 2-space JSON + trailing newline (matching the repo's other generated JSON).
30
+ */
31
+ export declare function serializeScaffoldSidecar(entries: readonly SidecarEntry[]): string;
32
+ /** Inputs to the pure per-file refresh decision. */
33
+ export interface ManagedFileDecisionInput {
34
+ /** Canonical content the toolkit would render for this file. */
35
+ render: string;
36
+ /** Current on-disk content, or `null` when the file is missing. */
37
+ current: string | null;
38
+ /** Hash recorded in the sidecar for this file, or `null` when untracked. */
39
+ recordedHash: string | null;
40
+ /** Whether `--force` was given. */
41
+ force: boolean;
42
+ }
43
+ /** Result of the pure per-file refresh decision. */
44
+ export interface ManagedFileDecision {
45
+ status: RefreshOutcome['status'];
46
+ /** Whether to write `render` to disk. */
47
+ write: boolean;
48
+ /** Hash to record in the new sidecar, or `null` to preserve the prior entry (or stay untracked). */
49
+ recordHash: string | null;
50
+ }
51
+ /**
52
+ * Decide what to do with one managed scaffold file. Pure — all filesystem state is passed in — so
53
+ * the decision table is unit-testable in isolation.
54
+ *
55
+ * | On-disk state | Result |
56
+ * |-------------------------------------------------|---------------|
57
+ * | missing | `recreated` |
58
+ * | matches the current render | `unchanged` |
59
+ * | differs from render, matches recorded hash | `updated` |
60
+ * | differs from render & recorded (or untracked) | `conflict` * |
61
+ * | …same, with `force` | `overwritten` |
62
+ *
63
+ * \* `unchanged` also adopts an untracked-but-in-sync file by recording its hash.
64
+ */
65
+ export declare function decideManagedFile(input: ManagedFileDecisionInput): ManagedFileDecision;
66
+ /**
67
+ * Seed `.aipm/scaffold.json` for a freshly scaffolded repo, recording the hash of every managed
68
+ * scaffold file as just written by `aipm init`. Called by {@link runInit} after the seed tree is
69
+ * written so the first `--refresh` has a baseline.
70
+ */
71
+ export declare function writeScaffoldSidecar(repoRoot: string): void;
72
+ /**
73
+ * Refresh the toolkit-owned scaffold files of an existing repo at `repoRoot`, re-rendering each
74
+ * from the installed tooling and updating it in place when safe (see {@link decideManagedFile}).
75
+ * Writes the updated `.aipm/scaffold.json` sidecar and returns one {@link RefreshOutcome} per
76
+ * managed file. Never throws on conflict — conflicts are reported, not failures.
77
+ */
78
+ export declare function runRefreshScaffold(repoRoot: string, opts?: RefreshOptions): RefreshOutcome[];
79
+ export {};
80
+ //# sourceMappingURL=scaffold-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-refresh.d.ts","sourceRoot":"","sources":["../../src/pipeline/scaffold-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjE,kGAAkG;AAClG,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAOD,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAGjF;AA+BD,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,oGAAoG;IACpG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,CAmBtF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ3D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,cAAc,EAAE,CAmChG"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * `aipm init --refresh` — keep a marketplace repo's **toolkit-owned scaffold files** (the CI
3
+ * workflow and `.gitignore`) in sync with the installed tooling, and serve as the upgrade path for
4
+ * any marketplace repo after `pnpm up @ai-plugin-marketplace/*`.
5
+ *
6
+ * Safety rests on a content-hash sidecar at `.aipm/scaffold.json` (mirroring the root-emission
7
+ * sidecar `.aipm/generated-root.json`): it records a hash of the exact content the toolkit last
8
+ * wrote each managed file. Refresh updates a file only when it is still pristine (matches the
9
+ * recorded hash) or missing; a file the user has edited surfaces as a reported conflict and is left
10
+ * untouched unless `--force` is given. A repo with no sidecar entry bootstraps: an already-in-sync
11
+ * file is adopted silently, a diverged one is a conflict to review.
12
+ *
13
+ * The managed set is deliberately narrow — only the pure tooling-recipe files (see
14
+ * {@link buildManagedScaffoldFiles}). `package.json` (deps are `pnpm up`'s job), `aipm.workspace.ts`
15
+ * (repo identity), `README.md` (authored), plugins, and `aipm build` output are never touched.
16
+ *
17
+ * @see docs/specs/scaffold-refresh-and-upgrade.md
18
+ */
19
+ import { createHash } from 'node:crypto';
20
+ import * as fs from 'node:fs';
21
+ import * as path from 'node:path';
22
+ import { buildManagedScaffoldFiles } from './init-template.js';
23
+ /** Sidecar location relative to the repo root. */
24
+ const SIDECAR_REL = ['.aipm', 'scaffold.json'];
25
+ /** Schema version of the sidecar payload. */
26
+ const SIDECAR_VERSION = 1;
27
+ /** Absolute path of the scaffold sidecar under `repoRoot`. */
28
+ function sidecarPath(repoRoot) {
29
+ return path.join(repoRoot, ...SIDECAR_REL);
30
+ }
31
+ /** Content hash recorded in the sidecar. `sha256-`-prefixed hex over the UTF-8 bytes. */
32
+ export function hashScaffoldContent(content) {
33
+ return `sha256-${createHash('sha256').update(content, 'utf-8').digest('hex')}`;
34
+ }
35
+ /**
36
+ * Serialize a sidecar payload: `{ version, files }` with `files` sorted by path for determinism,
37
+ * 2-space JSON + trailing newline (matching the repo's other generated JSON).
38
+ */
39
+ export function serializeScaffoldSidecar(entries) {
40
+ const files = [...entries].sort((a, b) => a.path.localeCompare(b.path));
41
+ return `${JSON.stringify({ version: SIDECAR_VERSION, files }, null, 2)}\n`;
42
+ }
43
+ /** Read the prior sidecar into a `path → hash` map. Missing or malformed sidecar → empty map. */
44
+ function readSidecar(repoRoot) {
45
+ const map = new Map();
46
+ const abs = sidecarPath(repoRoot);
47
+ if (!fs.existsSync(abs))
48
+ return map;
49
+ // Read errors (permissions, transient I/O) propagate — they are real operational problems, not a
50
+ // "malformed sidecar" we should silently swallow. Only a JSON parse failure is tolerated.
51
+ const raw = fs.readFileSync(abs, 'utf-8');
52
+ let parsed;
53
+ try {
54
+ parsed = JSON.parse(raw);
55
+ }
56
+ catch {
57
+ // A malformed sidecar is treated as absent: every managed file becomes "untracked" and must
58
+ // either already match the current render (adopted) or be resolved via --force.
59
+ return map;
60
+ }
61
+ if (Array.isArray(parsed.files)) {
62
+ for (const rawEntry of parsed.files) {
63
+ const entry = rawEntry;
64
+ if (typeof entry.path === 'string' && typeof entry.hash === 'string') {
65
+ map.set(entry.path, entry.hash);
66
+ }
67
+ }
68
+ }
69
+ return map;
70
+ }
71
+ /**
72
+ * Decide what to do with one managed scaffold file. Pure — all filesystem state is passed in — so
73
+ * the decision table is unit-testable in isolation.
74
+ *
75
+ * | On-disk state | Result |
76
+ * |-------------------------------------------------|---------------|
77
+ * | missing | `recreated` |
78
+ * | matches the current render | `unchanged` |
79
+ * | differs from render, matches recorded hash | `updated` |
80
+ * | differs from render & recorded (or untracked) | `conflict` * |
81
+ * | …same, with `force` | `overwritten` |
82
+ *
83
+ * \* `unchanged` also adopts an untracked-but-in-sync file by recording its hash.
84
+ */
85
+ export function decideManagedFile(input) {
86
+ const { render, current, recordedHash, force } = input;
87
+ const renderHash = hashScaffoldContent(render);
88
+ if (current === null)
89
+ return { status: 'recreated', write: true, recordHash: renderHash };
90
+ const currentHash = hashScaffoldContent(current);
91
+ if (currentHash === renderHash)
92
+ return { status: 'unchanged', write: false, recordHash: renderHash };
93
+ // Content differs from the current render.
94
+ if (recordedHash !== null && currentHash === recordedHash) {
95
+ // Pristine: the file is exactly what the toolkit last wrote, so it is safe to upgrade.
96
+ return { status: 'updated', write: true, recordHash: renderHash };
97
+ }
98
+ // Diverged from the recorded hash (user-edited) or untracked and not in sync.
99
+ if (force)
100
+ return { status: 'overwritten', write: true, recordHash: renderHash };
101
+ return { status: 'conflict', write: false, recordHash: null };
102
+ }
103
+ /**
104
+ * Seed `.aipm/scaffold.json` for a freshly scaffolded repo, recording the hash of every managed
105
+ * scaffold file as just written by `aipm init`. Called by {@link runInit} after the seed tree is
106
+ * written so the first `--refresh` has a baseline.
107
+ */
108
+ export function writeScaffoldSidecar(repoRoot) {
109
+ const entries = buildManagedScaffoldFiles().map((file) => ({
110
+ path: file.path,
111
+ hash: hashScaffoldContent(file.content),
112
+ }));
113
+ const abs = sidecarPath(repoRoot);
114
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
115
+ fs.writeFileSync(abs, serializeScaffoldSidecar(entries), 'utf-8');
116
+ }
117
+ /**
118
+ * Refresh the toolkit-owned scaffold files of an existing repo at `repoRoot`, re-rendering each
119
+ * from the installed tooling and updating it in place when safe (see {@link decideManagedFile}).
120
+ * Writes the updated `.aipm/scaffold.json` sidecar and returns one {@link RefreshOutcome} per
121
+ * managed file. Never throws on conflict — conflicts are reported, not failures.
122
+ */
123
+ export function runRefreshScaffold(repoRoot, opts = {}) {
124
+ const force = opts.force ?? false;
125
+ const resolved = path.resolve(repoRoot);
126
+ const recorded = readSidecar(resolved);
127
+ const outcomes = [];
128
+ const newEntries = [];
129
+ for (const file of buildManagedScaffoldFiles()) {
130
+ const abs = path.join(resolved, file.path);
131
+ const current = fs.existsSync(abs) ? fs.readFileSync(abs, 'utf-8') : null;
132
+ const recordedHash = recorded.get(file.path) ?? null;
133
+ const decision = decideManagedFile({ render: file.content, current, recordedHash, force });
134
+ if (decision.write) {
135
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
136
+ fs.writeFileSync(abs, file.content, 'utf-8');
137
+ }
138
+ if (decision.recordHash !== null) {
139
+ newEntries.push({ path: file.path, hash: decision.recordHash });
140
+ }
141
+ else if (recordedHash !== null) {
142
+ // Conflict left untouched: preserve the prior recorded hash so it stays tracked.
143
+ newEntries.push({ path: file.path, hash: recordedHash });
144
+ }
145
+ outcomes.push({ path: file.path, status: decision.status });
146
+ }
147
+ const sidecarAbs = sidecarPath(resolved);
148
+ fs.mkdirSync(path.dirname(sidecarAbs), { recursive: true });
149
+ fs.writeFileSync(sidecarAbs, serializeScaffoldSidecar(newEntries), 'utf-8');
150
+ return outcomes;
151
+ }
152
+ //# sourceMappingURL=scaffold-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-refresh.js","sourceRoot":"","sources":["../../src/pipeline/scaffold-refresh.ts"],"names":[],"mappings":"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"}
@@ -139,6 +139,44 @@ export interface InitOptions {
139
139
  * directory.
140
140
  */
141
141
  name?: string;
142
+ /**
143
+ * Version of `@ai-plugin-marketplace/cli` to pin the generated `package.json`'s `cli`
144
+ * dev dependency to (as `^<cliVersion>`). The cli entrypoint supplies its own version here; cli
145
+ * and core ship independently and may differ (e.g. `cli 0.1.1` ships with `core 0.2.0`). When
146
+ * omitted, falls back to core's own version (the historical lockstep assumption).
147
+ */
148
+ cliVersion?: string;
149
+ }
150
+ /**
151
+ * Options for {@link refreshScaffold}.
152
+ *
153
+ * @public
154
+ */
155
+ export interface RefreshOptions {
156
+ /**
157
+ * Overwrite toolkit-owned scaffold files even when their on-disk content has diverged from what
158
+ * the toolkit last wrote (i.e. the user edited them). Without this, diverged files are reported
159
+ * as conflicts and left untouched.
160
+ */
161
+ force?: boolean;
162
+ }
163
+ /**
164
+ * Per-file outcome of a {@link refreshScaffold} run. Returned (one per managed scaffold file) so
165
+ * the CLI can report what changed without re-deriving it.
166
+ *
167
+ * @public
168
+ */
169
+ export interface RefreshOutcome {
170
+ /** Repo-relative POSIX path of the managed scaffold file. */
171
+ path: string;
172
+ /**
173
+ * - `updated` — content changed and was rewritten (file was pristine or `--force`).
174
+ * - `unchanged` — already matched the current render; nothing written.
175
+ * - `recreated` — file was missing and was written from the render.
176
+ * - `conflict` — on-disk content diverged from the recorded hash; left untouched (no `--force`).
177
+ * - `overwritten` — diverged but rewritten because `--force` was set.
178
+ */
179
+ status: 'updated' | 'unchanged' | 'recreated' | 'conflict' | 'overwritten';
142
180
  }
143
181
  /**
144
182
  * Options for {@link migrate}.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-plugin-marketplace/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Core build pipeline, validation, and scaffolding for the AI plugin marketplace toolkit.",
5
5
  "type": "module",
6
6
  "author": "Mike North <michael.l.north@gmail.com>",