@moxxy/plugin-self-update 0.26.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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/dist/classify.d.ts +33 -0
  3. package/dist/classify.d.ts.map +1 -0
  4. package/dist/classify.js +177 -0
  5. package/dist/classify.js.map +1 -0
  6. package/dist/core-tools/apply.d.ts +4 -0
  7. package/dist/core-tools/apply.d.ts.map +1 -0
  8. package/dist/core-tools/apply.js +43 -0
  9. package/dist/core-tools/apply.js.map +1 -0
  10. package/dist/core-tools/begin.d.ts +4 -0
  11. package/dist/core-tools/begin.d.ts.map +1 -0
  12. package/dist/core-tools/begin.js +76 -0
  13. package/dist/core-tools/begin.js.map +1 -0
  14. package/dist/core-tools/edit.d.ts +4 -0
  15. package/dist/core-tools/edit.d.ts.map +1 -0
  16. package/dist/core-tools/edit.js +33 -0
  17. package/dist/core-tools/edit.js.map +1 -0
  18. package/dist/core-tools/index.d.ts +11 -0
  19. package/dist/core-tools/index.d.ts.map +1 -0
  20. package/dist/core-tools/index.js +28 -0
  21. package/dist/core-tools/index.js.map +1 -0
  22. package/dist/core-tools/preflight.d.ts +4 -0
  23. package/dist/core-tools/preflight.d.ts.map +1 -0
  24. package/dist/core-tools/preflight.js +14 -0
  25. package/dist/core-tools/preflight.js.map +1 -0
  26. package/dist/core-tools/rollback.d.ts +4 -0
  27. package/dist/core-tools/rollback.d.ts.map +1 -0
  28. package/dist/core-tools/rollback.js +30 -0
  29. package/dist/core-tools/rollback.js.map +1 -0
  30. package/dist/core-tools/shared.d.ts +16 -0
  31. package/dist/core-tools/shared.d.ts.map +1 -0
  32. package/dist/core-tools/shared.js +12 -0
  33. package/dist/core-tools/shared.js.map +1 -0
  34. package/dist/core-tools/status.d.ts +4 -0
  35. package/dist/core-tools/status.d.ts.map +1 -0
  36. package/dist/core-tools/status.js +25 -0
  37. package/dist/core-tools/status.js.map +1 -0
  38. package/dist/core-tools/verify.d.ts +4 -0
  39. package/dist/core-tools/verify.d.ts.map +1 -0
  40. package/dist/core-tools/verify.js +39 -0
  41. package/dist/core-tools/verify.js.map +1 -0
  42. package/dist/core-tools/write.d.ts +4 -0
  43. package/dist/core-tools/write.d.ts.map +1 -0
  44. package/dist/core-tools/write.js +28 -0
  45. package/dist/core-tools/write.js.map +1 -0
  46. package/dist/core-update.d.ts +173 -0
  47. package/dist/core-update.d.ts.map +1 -0
  48. package/dist/core-update.js +626 -0
  49. package/dist/core-update.js.map +1 -0
  50. package/dist/deps.d.ts +49 -0
  51. package/dist/deps.d.ts.map +1 -0
  52. package/dist/deps.js +30 -0
  53. package/dist/deps.js.map +1 -0
  54. package/dist/index.d.ts +22 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +349 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/transaction.d.ts +80 -0
  59. package/dist/transaction.d.ts.map +1 -0
  60. package/dist/transaction.js +188 -0
  61. package/dist/transaction.js.map +1 -0
  62. package/dist/verify.d.ts +23 -0
  63. package/dist/verify.d.ts.map +1 -0
  64. package/dist/verify.js +164 -0
  65. package/dist/verify.js.map +1 -0
  66. package/package.json +61 -0
  67. package/src/classify.test.ts +176 -0
  68. package/src/classify.ts +221 -0
  69. package/src/core-tools/apply.ts +44 -0
  70. package/src/core-tools/begin.ts +94 -0
  71. package/src/core-tools/edit.ts +33 -0
  72. package/src/core-tools/index.ts +33 -0
  73. package/src/core-tools/preflight.ts +15 -0
  74. package/src/core-tools/rollback.ts +30 -0
  75. package/src/core-tools/shared.test.ts +16 -0
  76. package/src/core-tools/shared.ts +24 -0
  77. package/src/core-tools/status.ts +26 -0
  78. package/src/core-tools/verify.ts +39 -0
  79. package/src/core-tools/write.ts +30 -0
  80. package/src/core-update.test.ts +542 -0
  81. package/src/core-update.ts +744 -0
  82. package/src/deps.ts +84 -0
  83. package/src/discovery.test.ts +40 -0
  84. package/src/index.test.ts +299 -0
  85. package/src/index.ts +441 -0
  86. package/src/transaction.test.ts +143 -0
  87. package/src/transaction.ts +254 -0
  88. package/src/verify.test.ts +82 -0
  89. package/src/verify.ts +200 -0
package/dist/deps.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import type { SessionId, ToolContext, TurnId } from '@moxxy/sdk';
2
+ import type { RegistrySnapshot } from './transaction.js';
3
+ import { type CoreInstallInfo } from './core-update.js';
4
+ export declare const PLUGIN_ID = "@moxxy/plugin-self-update";
5
+ export interface SkipInfo {
6
+ readonly pluginName: string;
7
+ readonly packageName?: string;
8
+ readonly message: string;
9
+ }
10
+ export interface SelfUpdateEmit {
11
+ readonly subtype: string;
12
+ readonly payload: unknown;
13
+ readonly sessionId: SessionId;
14
+ readonly turnId: TurnId;
15
+ }
16
+ export interface SelfUpdateDeps {
17
+ /** Base user dir, normally `~/.moxxy`. Overridable for tests. */
18
+ readonly moxxyDir: string;
19
+ /** Hot-reload the plugin host (rescans user plugin dirs). */
20
+ readonly reload: () => Promise<void>;
21
+ /** Unload a plugin by name so a modified version re-imports fresh on reload. */
22
+ readonly unload: (name: string) => Promise<void>;
23
+ /** Current registered contribution names per kind. */
24
+ readonly snapshot: () => RegistrySnapshot;
25
+ /** Plugins the host failed to load (so we can surface a load error). */
26
+ readonly skipped: () => ReadonlyArray<SkipInfo>;
27
+ /** Append a `plugin_event` audit record. Best-effort. */
28
+ readonly emit: (e: SelfUpdateEmit) => Promise<void>;
29
+ /** How many terminal transactions to keep on GC. Default 5. */
30
+ readonly maxTxnRetained?: number;
31
+ /** Tier-2 core-patching config. Omit or set enabled:false to hide core tools. */
32
+ readonly coreUpdate?: {
33
+ /** Enable the Tier-2 core-update tools. Default true. */
34
+ readonly enabled?: boolean;
35
+ /** Module URL used to resolve the live @moxxy/core install. Default import.meta.url. */
36
+ readonly fromUrl?: string;
37
+ /** Override the git repository URL (else read from @moxxy/core package.json). */
38
+ readonly repoUrlOverride?: string;
39
+ };
40
+ }
41
+ export declare function readJsonName(dir: string): Promise<string | undefined>;
42
+ export declare function findSkip(skipped: ReadonlyArray<SkipInfo>, names: ReadonlyArray<string>): SkipInfo | undefined;
43
+ export declare function emitSafe(deps: SelfUpdateDeps, ctx: ToolContext, subtype: string, payload: unknown): Promise<void>;
44
+ /**
45
+ * The fromUrl default is provided by the caller — `detectCoreInstall` resolves
46
+ * the live `@moxxy/core` install relative to that module URL.
47
+ */
48
+ export declare function resolveCoreInstall(deps: SelfUpdateDeps, fromUrlDefault: string): CoreInstallInfo | null;
49
+ //# sourceMappingURL=deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE3E,eAAO,MAAM,SAAS,8BAA8B,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,gBAAgB,CAAC;IAC1C,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,iFAAiF;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,yDAAyD;QACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,wFAAwF;QACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,iFAAiF;QACjF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS3E;AAED,wBAAgB,QAAQ,CACtB,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,EAChC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAC3B,QAAQ,GAAG,SAAS,CAGtB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAEvG"}
package/dist/deps.js ADDED
@@ -0,0 +1,30 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { detectCoreInstall } from './core-update.js';
4
+ export const PLUGIN_ID = '@moxxy/plugin-self-update';
5
+ export async function readJsonName(dir) {
6
+ try {
7
+ const pkg = JSON.parse(await fs.readFile(path.join(dir, 'package.json'), 'utf8'));
8
+ return pkg.name;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ export function findSkip(skipped, names) {
15
+ const want = new Set(names.filter(Boolean));
16
+ return skipped.find((s) => want.has(s.pluginName) || (s.packageName ? want.has(s.packageName) : false));
17
+ }
18
+ export async function emitSafe(deps, ctx, subtype, payload) {
19
+ await deps
20
+ .emit({ subtype, payload, sessionId: ctx.sessionId, turnId: ctx.turnId })
21
+ .catch(() => undefined);
22
+ }
23
+ /**
24
+ * The fromUrl default is provided by the caller — `detectCoreInstall` resolves
25
+ * the live `@moxxy/core` install relative to that module URL.
26
+ */
27
+ export function resolveCoreInstall(deps, fromUrlDefault) {
28
+ return detectCoreInstall(deps.coreUpdate?.fromUrl ?? fromUrlDefault);
29
+ }
30
+ //# sourceMappingURL=deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../src/deps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAwB,MAAM,kBAAkB,CAAC;AAE3E,MAAM,CAAC,MAAM,SAAS,GAAG,2BAA2B,CAAC;AAyCrD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE/E,CAAC;QACF,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,OAAgC,EAChC,KAA4B;IAE5B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1G,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAoB,EACpB,GAAgB,EAChB,OAAe,EACf,OAAgB;IAEhB,MAAM,IAAI;SACP,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;SACxE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAoB,EAAE,cAAsB;IAC7E,OAAO,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,cAAc,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type LifecycleHooks, type Plugin } from '@moxxy/sdk';
2
+ import { type SelfUpdateDeps } from './deps.js';
3
+ export type { SelfUpdateDeps, SelfUpdateEmit, SkipInfo } from './deps.js';
4
+ export { beginTransaction, restoreSnapshot, listTransactions, gcTransactions, type Journal, type RegistrySnapshot, } from './transaction.js';
5
+ export { classify, gatherSignals, type ClassifyResult } from './classify.js';
6
+ export { finalizeStagedCoreUpdate, gcCoreTxns, listCoreTxns, detectCoreInstall, readCoreJournal, restoreOverlay, reconcileOverlay, corePreflight, type CoreJournal, type CoreInstallInfo, } from './core-update.js';
7
+ export declare function buildSelfUpdatePlugin(deps: SelfUpdateDeps, hooks?: LifecycleHooks): Plugin;
8
+ /**
9
+ * Discovery-loadable default export. Resolves the plugin host (`'pluginHost'`),
10
+ * the registry-name snapshot (`'registrySnapshot'`), the writable event-append
11
+ * (`'appendEvent'` — the counterpart to the read-only `ctx.log`) and this
12
+ * plugin's config options (`'getPluginOptions'`) from the inter-plugin service
13
+ * registry in `onInit`, instead of the host `SelfUpdateDeps` closure.
14
+ *
15
+ * The Tier-2 core-update tools are gated at BUILD time on
16
+ * `MOXXY_NO_CORE_UPDATE` (the env the desktop sets to hide them); the softer
17
+ * `allowCoreUpdate`/`repoUrl` config prefs are resolved in `onInit` and applied
18
+ * to `coreUpdate.repoUrlOverride` + the GC retention.
19
+ */
20
+ export declare const selfUpdatePlugin: Plugin;
21
+ export default selfUpdatePlugin;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,MAAM,EAGZ,MAAM,YAAY,CAAC;AAkBpB,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAG7F,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1E,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,wBAAwB,EACxB,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,MAAM,CAW1F;AAQD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAyD3B,CAAC;AAuSL,eAAe,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,349 @@
1
+ import * as os from 'node:os';
2
+ import * as path from 'node:path';
3
+ import { asPluginId, definePlugin, defineTool, z, } from '@moxxy/sdk';
4
+ import { MAX_FAILED_ATTEMPTS, beginTransaction, diffSnapshot, failedAttemptCount, gcTransactions, listTransactions, readJournal, recordAttempt, resolveTarget, restoreSnapshot, writeJournal, } from './transaction.js';
5
+ import { classify, gatherSignals } from './classify.js';
6
+ import { verifyPluginBuild, verifySkillFile } from './verify.js';
7
+ import { PLUGIN_ID, emitSafe, findSkip, readJsonName } from './deps.js';
8
+ import { coreTools } from './core-tools/index.js';
9
+ export { beginTransaction, restoreSnapshot, listTransactions, gcTransactions, } from './transaction.js';
10
+ export { classify, gatherSignals } from './classify.js';
11
+ export { finalizeStagedCoreUpdate, gcCoreTxns, listCoreTxns, detectCoreInstall, readCoreJournal, restoreOverlay, reconcileOverlay, corePreflight, } from './core-update.js';
12
+ export function buildSelfUpdatePlugin(deps, hooks) {
13
+ const tools = [
14
+ classifyTool(deps),
15
+ beginTool(deps),
16
+ verifyTool(deps),
17
+ applyTool(deps),
18
+ rollbackTool(deps),
19
+ statusTool(deps),
20
+ ];
21
+ if (deps.coreUpdate?.enabled !== false)
22
+ tools.push(...coreTools(deps, import.meta.url));
23
+ return definePlugin({ name: PLUGIN_ID, version: '0.0.0', tools, ...(hooks ? { hooks } : {}) });
24
+ }
25
+ /**
26
+ * Discovery-loadable default export. Resolves the plugin host (`'pluginHost'`),
27
+ * the registry-name snapshot (`'registrySnapshot'`), the writable event-append
28
+ * (`'appendEvent'` — the counterpart to the read-only `ctx.log`) and this
29
+ * plugin's config options (`'getPluginOptions'`) from the inter-plugin service
30
+ * registry in `onInit`, instead of the host `SelfUpdateDeps` closure.
31
+ *
32
+ * The Tier-2 core-update tools are gated at BUILD time on
33
+ * `MOXXY_NO_CORE_UPDATE` (the env the desktop sets to hide them); the softer
34
+ * `allowCoreUpdate`/`repoUrl` config prefs are resolved in `onInit` and applied
35
+ * to `coreUpdate.repoUrlOverride` + the GC retention.
36
+ */
37
+ export const selfUpdatePlugin = (() => {
38
+ let host = null;
39
+ let snapshotFn = null;
40
+ let appendEvent = null;
41
+ let options = {};
42
+ const deps = {
43
+ moxxyDir: path.join(os.homedir(), '.moxxy'),
44
+ reload: () => host?.reload() ?? Promise.resolve(),
45
+ unload: (name) => host?.unload(name) ?? Promise.resolve(),
46
+ snapshot: () => (snapshotFn ? snapshotFn() : {}),
47
+ skipped: () => (host?.listSkipped() ?? []).map((s) => ({
48
+ pluginName: s.pluginName,
49
+ ...(s.packageName ? { packageName: s.packageName } : {}),
50
+ message: s.message,
51
+ })),
52
+ emit: (e) => appendEvent
53
+ ? appendEvent({
54
+ type: 'plugin_event',
55
+ pluginId: asPluginId(PLUGIN_ID),
56
+ subtype: e.subtype,
57
+ payload: e.payload,
58
+ sessionId: e.sessionId,
59
+ turnId: e.turnId,
60
+ source: 'plugin',
61
+ })
62
+ : Promise.resolve(),
63
+ get maxTxnRetained() {
64
+ return typeof options.maxTxnRetained === 'number' ? options.maxTxnRetained : undefined;
65
+ },
66
+ coreUpdate: {
67
+ // Gated at build on the env (the desktop sets MOXXY_NO_CORE_UPDATE=1 to
68
+ // hide the tools); the config `allowCoreUpdate` pref can't gate build-time
69
+ // tool inclusion under discovery-loading, but repoUrl is honored at run.
70
+ enabled: process.env.MOXXY_NO_CORE_UPDATE !== '1',
71
+ fromUrl: import.meta.url,
72
+ get repoUrlOverride() {
73
+ return typeof options.repoUrl === 'string' ? options.repoUrl : undefined;
74
+ },
75
+ },
76
+ };
77
+ const hooks = {
78
+ onInit: (ctx) => {
79
+ host = ctx.services.get('pluginHost') ?? null;
80
+ snapshotFn = ctx.services.get('registrySnapshot') ?? null;
81
+ appendEvent = ctx.services.get('appendEvent') ?? null;
82
+ const getOptions = ctx.services.get('getPluginOptions');
83
+ options = getOptions?.(PLUGIN_ID) ?? {};
84
+ },
85
+ };
86
+ return buildSelfUpdatePlugin(deps, hooks);
87
+ })();
88
+ // ── self_update_classify ────────────────────────────────────────────────────
89
+ function classifyTool(deps) {
90
+ return defineTool({
91
+ name: 'self_update_classify',
92
+ description: 'Read-only. Inspect recent errors / failed tool calls and the registered tool set, then recommend the LOWEST-risk way to satisfy a self-update: a skill (instructions), a plugin (new tool / behavior override), or a core patch (escalate). Advisory only — you make the final call. Call this first when asked to add a capability or to fix a recurring failure.',
93
+ inputSchema: z.object({
94
+ trigger: z.enum(['error', 'request']).describe('Whether this follows an error or a user request.'),
95
+ text: z.string().optional().describe('The user request or a short description of the problem.'),
96
+ }),
97
+ permission: { action: 'allow' },
98
+ handler: (input, ctx) => {
99
+ const signals = gatherSignals(ctx.log, deps.snapshot().tools ?? []);
100
+ return classify(input, signals);
101
+ },
102
+ });
103
+ }
104
+ // ── self_update_begin ─────────────────────────────────────────────────────────
105
+ function beginTool(deps) {
106
+ return defineTool({
107
+ name: 'self_update_begin',
108
+ description: 'Open a self-update transaction for a target plugin (dir under ~/.moxxy/plugins) or skill (~/.moxxy/skills/<name>.md). Snapshots the current state so the change can be rolled back. Returns a txnId. Make your edits with Write/Edit AFTER this, then call self_update_verify.',
109
+ inputSchema: z.object({
110
+ kind: z.enum(['plugin', 'skill']),
111
+ name: z
112
+ .string()
113
+ .min(1)
114
+ .describe('Plugin directory name or skill slug (no path separators).'),
115
+ }),
116
+ permission: { action: 'allow' },
117
+ handler: async (input, ctx) => {
118
+ // Single-flight per target (mirrors the Tier-2 core_begin guard): two
119
+ // concurrent begins on the same plugin/skill snapshot independently, so a
120
+ // second begin started after the model already overwrote the artifact
121
+ // captures the BROKEN state into its own `before/`, and a later rollback
122
+ // of that txn "restores" garbage. Refuse a new begin while a non-terminal
123
+ // txn for the same target is open. resolveTarget also validates the name.
124
+ const target = resolveTarget(deps.moxxyDir, input.kind, input.name);
125
+ const active = (await listTransactions(deps.moxxyDir)).find((j) => j.target.path === target.path && (j.state === 'open' || j.state === 'verified'));
126
+ if (active) {
127
+ throw new Error(`a self-update is already in progress for ${input.kind} "${input.name}" ` +
128
+ `(txn ${active.txnId}, state "${active.state}"). Finish it (self_update_verify → ` +
129
+ `self_update_apply) or discard it with self_update_rollback({ txnId: "${active.txnId}" }) ` +
130
+ `before starting another.`);
131
+ }
132
+ const journal = await beginTransaction({ moxxyDir: deps.moxxyDir, kind: input.kind, name: input.name });
133
+ if (input.kind === 'plugin') {
134
+ journal.registryBefore = deps.snapshot();
135
+ await writeJournal(deps.moxxyDir, journal);
136
+ }
137
+ await emitSafe(deps, ctx, 'begin', {
138
+ txnId: journal.txnId,
139
+ target: journal.target,
140
+ existedBefore: journal.existedBefore,
141
+ });
142
+ return {
143
+ txnId: journal.txnId,
144
+ target: journal.target,
145
+ existedBefore: journal.existedBefore,
146
+ next: 'Write/Edit the files, then call self_update_verify with this txnId.',
147
+ };
148
+ },
149
+ });
150
+ }
151
+ // ── self_update_verify ──────────────────────────────────────────────────────
152
+ function verifyTool(deps) {
153
+ return defineTool({
154
+ name: 'self_update_verify',
155
+ description: 'Build, test and load-check the change in a transaction, then hot-reload it into the live session. Returns the stage results and what registered. On failure of a modify, the previous working version is automatically restored. Refuses after 2 failed cycles (escalate to the user). Run AFTER your edits; if it passes, call self_update_apply.',
156
+ inputSchema: z.object({ txnId: z.string().min(1) }),
157
+ permission: { action: 'prompt' },
158
+ handler: async (input, ctx) => {
159
+ const journal = await readJournal(deps.moxxyDir, input.txnId);
160
+ if (failedAttemptCount(journal) >= MAX_FAILED_ATTEMPTS) {
161
+ await escalate(deps, ctx, journal, 'too many failed verify cycles');
162
+ return {
163
+ ok: false,
164
+ escalate: true,
165
+ message: `Already failed ${MAX_FAILED_ATTEMPTS} times — stopping. Rolled back to a clean state; tell the user what you tried and the errors.`,
166
+ attempts: journal.attempts,
167
+ };
168
+ }
169
+ const result = journal.target.kind === 'plugin'
170
+ ? await verifyPlugin(deps, journal)
171
+ : await verifySkill(journal);
172
+ if (!result.ok) {
173
+ recordAttempt(journal, { stage: result.failedStage ?? 'verify', ok: false, message: result.message });
174
+ let recovered = false;
175
+ if (journal.existedBefore) {
176
+ await restoreSnapshot(deps.moxxyDir, journal);
177
+ if (journal.target.kind === 'plugin') {
178
+ await deps.unload(journal.target.name).catch(() => undefined);
179
+ await deps.reload();
180
+ }
181
+ recovered = true;
182
+ }
183
+ const cap = failedAttemptCount(journal) >= MAX_FAILED_ATTEMPTS;
184
+ if (cap) {
185
+ // We may have just restored the snapshot above. Tell escalate() the
186
+ // rollback is done so it doesn't repeat the recursive filesystem copy
187
+ // + plugin-host rescan (escalate skips its restore when already
188
+ // rolled_back). It still flips state to 'escalated' and persists.
189
+ if (recovered)
190
+ journal.state = 'rolled_back';
191
+ await escalate(deps, ctx, journal, result.message);
192
+ }
193
+ else {
194
+ await writeJournal(deps.moxxyDir, journal);
195
+ }
196
+ await emitSafe(deps, ctx, 'verify_failed', { txnId: journal.txnId, message: result.message });
197
+ return {
198
+ ok: false,
199
+ escalate: cap,
200
+ recovered,
201
+ stages: result.stages,
202
+ message: result.message,
203
+ remainingAttempts: Math.max(0, MAX_FAILED_ATTEMPTS - failedAttemptCount(journal)),
204
+ };
205
+ }
206
+ recordAttempt(journal, { stage: 'verify', ok: true, message: 'all stages passed' });
207
+ journal.state = 'verified';
208
+ await writeJournal(deps.moxxyDir, journal);
209
+ await emitSafe(deps, ctx, 'verify_ok', { txnId: journal.txnId, registered: result.registered });
210
+ return {
211
+ ok: true,
212
+ stages: result.stages,
213
+ registered: result.registered,
214
+ next: 'Looks good — call self_update_apply to keep it, or self_update_rollback to discard.',
215
+ };
216
+ },
217
+ });
218
+ }
219
+ async function verifyPlugin(deps, journal) {
220
+ const target = journal.target;
221
+ const stages = [...(await verifyPluginBuild(target))];
222
+ const failed = stages.find((s) => !s.ok);
223
+ if (failed) {
224
+ return { ok: false, failedStage: failed.stage, message: `${failed.stage} failed: ${failed.message}`, stages };
225
+ }
226
+ // Activate: drop the old instance (if any) so a modified entry re-imports
227
+ // fresh, then rescan from disk.
228
+ await deps.unload(target.name).catch(() => undefined);
229
+ const pkgName = await readJsonName(target.path);
230
+ await deps.reload();
231
+ const skip = findSkip(deps.skipped(), [target.name, pkgName ?? '']);
232
+ if (skip) {
233
+ stages.push({ stage: 'load', ok: false, message: skip.message });
234
+ return { ok: false, failedStage: 'load', message: `plugin failed to load: ${skip.message}`, stages };
235
+ }
236
+ const after = deps.snapshot();
237
+ const registered = diffSnapshot(journal.registryBefore ?? {}, after);
238
+ if (!journal.existedBefore && Object.keys(registered).length === 0) {
239
+ stages.push({
240
+ stage: 'load',
241
+ ok: false,
242
+ message: 'plugin loaded but registered no tools/agents/etc. — check the entry exports a valid plugin',
243
+ });
244
+ return {
245
+ ok: false,
246
+ failedStage: 'load',
247
+ message: 'new plugin registered nothing (no valid contributions found)',
248
+ stages,
249
+ };
250
+ }
251
+ stages.push({ stage: 'load', ok: true, message: 'loaded and registered' });
252
+ return { ok: true, message: 'ok', stages, registered };
253
+ }
254
+ async function verifySkill(journal) {
255
+ const r = await verifySkillFile(journal.target);
256
+ if (!r.ok)
257
+ return { ok: false, failedStage: r.stage, message: r.message, stages: [r] };
258
+ return {
259
+ ok: true,
260
+ message: 'skill frontmatter valid (activate with reload_skills or on next launch)',
261
+ stages: [r],
262
+ };
263
+ }
264
+ // ── self_update_apply ───────────────────────────────────────────────────────
265
+ function applyTool(deps) {
266
+ return defineTool({
267
+ name: 'self_update_apply',
268
+ description: 'Finalize a verified self-update transaction: mark it committed and prune old snapshots. The change is already live (loaded during verify); this is the keep-it confirmation. Requires a prior successful self_update_verify.',
269
+ inputSchema: z.object({ txnId: z.string().min(1) }),
270
+ permission: { action: 'prompt' },
271
+ handler: async (input, ctx) => {
272
+ const journal = await readJournal(deps.moxxyDir, input.txnId);
273
+ if (journal.state !== 'verified') {
274
+ throw new Error(`transaction ${input.txnId} is "${journal.state}", not "verified" — run self_update_verify first`);
275
+ }
276
+ journal.state = 'committed';
277
+ await writeJournal(deps.moxxyDir, journal);
278
+ await emitSafe(deps, ctx, 'apply', { txnId: journal.txnId, target: journal.target });
279
+ await gcTransactions(deps.moxxyDir, deps.maxTxnRetained ?? 5).catch(() => undefined);
280
+ return { ok: true, committed: journal.target };
281
+ },
282
+ });
283
+ }
284
+ // ── self_update_rollback ────────────────────────────────────────────────────
285
+ function rollbackTool(deps) {
286
+ return defineTool({
287
+ name: 'self_update_rollback',
288
+ description: 'Undo a self-update transaction: restore the pre-change snapshot (or delete a newly-created artifact) and hot-reload. Use when a change built and loaded cleanly but behaves wrongly at runtime.',
289
+ inputSchema: z.object({
290
+ txnId: z.string().min(1),
291
+ reason: z.string().optional(),
292
+ }),
293
+ permission: { action: 'allow' },
294
+ handler: async (input, ctx) => {
295
+ const journal = await readJournal(deps.moxxyDir, input.txnId);
296
+ await restoreSnapshot(deps.moxxyDir, journal);
297
+ if (journal.target.kind === 'plugin') {
298
+ await deps.unload(journal.target.name).catch(() => undefined);
299
+ await deps.reload();
300
+ }
301
+ journal.state = 'rolled_back';
302
+ await writeJournal(deps.moxxyDir, journal);
303
+ await emitSafe(deps, ctx, 'rollback', { txnId: journal.txnId, reason: input.reason ?? null });
304
+ return { ok: true, restored: journal.target, existedBefore: journal.existedBefore };
305
+ },
306
+ });
307
+ }
308
+ // ── self_update_status ──────────────────────────────────────────────────────
309
+ function statusTool(deps) {
310
+ return defineTool({
311
+ name: 'self_update_status',
312
+ description: 'List self-update transactions and their state (open / verified / committed / rolled_back / escalated).',
313
+ inputSchema: z.object({ txnId: z.string().optional() }),
314
+ permission: { action: 'allow' },
315
+ handler: async (input) => {
316
+ const all = await listTransactions(deps.moxxyDir);
317
+ const rows = (input.txnId ? all.filter((j) => j.txnId === input.txnId) : all).map((j) => ({
318
+ txnId: j.txnId,
319
+ state: j.state,
320
+ target: j.target,
321
+ existedBefore: j.existedBefore,
322
+ failedAttempts: failedAttemptCount(j),
323
+ updatedAt: j.updatedAt,
324
+ }));
325
+ return { transactions: rows };
326
+ },
327
+ });
328
+ }
329
+ async function escalate(deps, ctx, journal, reason) {
330
+ if (journal.existedBefore && journal.state !== 'rolled_back') {
331
+ await restoreSnapshot(deps.moxxyDir, journal);
332
+ if (journal.target.kind === 'plugin') {
333
+ await deps.unload(journal.target.name).catch(() => undefined);
334
+ await deps.reload();
335
+ }
336
+ }
337
+ else if (!journal.existedBefore) {
338
+ // Clean up the failed new artifact so it doesn't linger half-built.
339
+ await restoreSnapshot(deps.moxxyDir, journal);
340
+ if (journal.target.kind === 'plugin')
341
+ await deps.reload();
342
+ }
343
+ journal.state = 'escalated';
344
+ await writeJournal(deps.moxxyDir, journal);
345
+ await emitSafe(deps, ctx, 'escalated', { txnId: journal.txnId, reason });
346
+ }
347
+ // Discovery entry: `createPluginLoader` requires a default Plugin export.
348
+ export default selfUpdatePlugin;
349
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Transactional bookkeeping for self-update. Every change to a user-scope
3
+ * artifact (a plugin directory or a skill file) is bracketed by a transaction:
4
+ * the target is snapshotted before edits, a persisted journal tracks state and
5
+ * failed attempts, and a rollback restores the snapshot (or deletes a freshly
6
+ * created artifact). This module is filesystem-only and imports no moxxy core,
7
+ * so it is trivially unit-testable against a temp directory.
8
+ */
9
+ export type TargetKind = 'plugin' | 'skill';
10
+ export type TxnState = 'open' | 'verified' | 'committed' | 'rolled_back' | 'escalated';
11
+ export interface TxnTarget {
12
+ readonly kind: TargetKind;
13
+ readonly name: string;
14
+ /** Absolute path to the artifact (a directory for plugins, a file for skills). */
15
+ readonly path: string;
16
+ }
17
+ export interface TxnAttempt {
18
+ readonly at: string;
19
+ readonly stage: string;
20
+ readonly ok: boolean;
21
+ readonly message: string;
22
+ }
23
+ /** Registered contribution names per kind — used to diff what a change added. */
24
+ export type RegistrySnapshot = Record<string, ReadonlyArray<string>>;
25
+ export interface Journal {
26
+ readonly txnId: string;
27
+ readonly createdAt: string;
28
+ updatedAt: string;
29
+ readonly target: TxnTarget;
30
+ /** Whether the artifact existed before this transaction. false ⇒ rollback deletes it. */
31
+ readonly existedBefore: boolean;
32
+ state: TxnState;
33
+ attempts: TxnAttempt[];
34
+ /** Registry contributions captured at begin time, for an added-since diff. */
35
+ registryBefore?: RegistrySnapshot;
36
+ }
37
+ /** Names present in `after` but not in `before`, per kind. Empty keys dropped. */
38
+ export declare function diffSnapshot(before: RegistrySnapshot, after: RegistrySnapshot): RegistrySnapshot;
39
+ /** Max failed verify cycles for one transaction before we force escalation. */
40
+ export declare const MAX_FAILED_ATTEMPTS = 2;
41
+ export declare function selfUpdateRoot(moxxyDir: string): string;
42
+ export declare function txnDir(moxxyDir: string, txnId: string): string;
43
+ /**
44
+ * Resolve the on-disk target for a (kind, name). Throws on unsafe names so a
45
+ * model-supplied name can never escape the user artifact directories.
46
+ */
47
+ export declare function resolveTarget(moxxyDir: string, kind: TargetKind, name: string): TxnTarget;
48
+ export declare function newTxnId(now?: Date): string;
49
+ /**
50
+ * Open a transaction: snapshot the current target (if any) into the txn dir
51
+ * and write the initial journal. Safe to call for a not-yet-existing target.
52
+ */
53
+ export declare function beginTransaction(opts: {
54
+ readonly moxxyDir: string;
55
+ readonly kind: TargetKind;
56
+ readonly name: string;
57
+ readonly now?: Date;
58
+ }): Promise<Journal>;
59
+ export declare function writeJournal(moxxyDir: string, journal: Journal): Promise<void>;
60
+ export declare function readJournal(moxxyDir: string, txnId: string): Promise<Journal>;
61
+ export declare function listTransactions(moxxyDir: string): Promise<ReadonlyArray<Journal>>;
62
+ export declare function recordAttempt(journal: Journal, attempt: Omit<TxnAttempt, 'at'>): void;
63
+ export declare function failedAttemptCount(journal: Journal): number;
64
+ /**
65
+ * Restore the target to its pre-transaction state: copy the snapshot back, or
66
+ * delete the artifact if it was newly created. Idempotent.
67
+ *
68
+ * The snapshot is source-only (SNAPSHOT_EXCLUDE drops node_modules/.git/dist),
69
+ * so a blanket `rm -rf` of the target before copying would wipe the installed
70
+ * runtime deps — and nothing re-installs them, leaving a plugin that fails to
71
+ * load on the very next deps.reload(). To keep the working `node_modules` (and
72
+ * the other reproducible-but-uncaptured dirs) across a MODIFICATION rollback, we
73
+ * remove only the captured source entries and overlay the snapshot back on top,
74
+ * never touching the excluded dirs. A newly-created target (no snapshot) is still
75
+ * deleted wholesale.
76
+ */
77
+ export declare function restoreSnapshot(moxxyDir: string, journal: Journal): Promise<void>;
78
+ /** Keep the most recent `keep` terminal transactions; delete older ones. */
79
+ export declare function gcTransactions(moxxyDir: string, keep: number): Promise<void>;
80
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"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"}