bkper 4.24.2 → 4.25.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 (82) hide show
  1. package/lib/agent/extensions/builtins.d.ts.map +1 -1
  2. package/lib/agent/extensions/builtins.js +2 -2
  3. package/lib/agent/extensions/builtins.js.map +1 -1
  4. package/lib/agent/extensions/handoff.d.ts +2 -13
  5. package/lib/agent/extensions/handoff.d.ts.map +1 -1
  6. package/lib/agent/extensions/handoff.js +37 -17
  7. package/lib/agent/extensions/handoff.js.map +1 -1
  8. package/lib/agent/interactive/interactive-mode.d.ts.map +1 -1
  9. package/lib/agent/interactive/interactive-mode.js +1 -10
  10. package/lib/agent/interactive/interactive-mode.js.map +1 -1
  11. package/lib/commands/apps/deploy.d.ts +3 -1
  12. package/lib/commands/apps/deploy.d.ts.map +1 -1
  13. package/lib/commands/apps/deploy.js +29 -4
  14. package/lib/commands/apps/deploy.js.map +1 -1
  15. package/lib/commands/apps/git/clone.d.ts +23 -0
  16. package/lib/commands/apps/git/clone.d.ts.map +1 -0
  17. package/lib/commands/apps/git/clone.js +161 -0
  18. package/lib/commands/apps/git/clone.js.map +1 -0
  19. package/lib/commands/apps/git/credentials.d.ts +35 -0
  20. package/lib/commands/apps/git/credentials.d.ts.map +1 -0
  21. package/lib/commands/apps/git/credentials.js +196 -0
  22. package/lib/commands/apps/git/credentials.js.map +1 -0
  23. package/lib/commands/apps/git/index.d.ts +12 -0
  24. package/lib/commands/apps/git/index.d.ts.map +1 -0
  25. package/lib/commands/apps/git/index.js +12 -0
  26. package/lib/commands/apps/git/index.js.map +1 -0
  27. package/lib/commands/apps/git/inspect.d.ts +26 -0
  28. package/lib/commands/apps/git/inspect.d.ts.map +1 -0
  29. package/lib/commands/apps/git/inspect.js +207 -0
  30. package/lib/commands/apps/git/inspect.js.map +1 -0
  31. package/lib/commands/apps/git/markers.d.ts +16 -0
  32. package/lib/commands/apps/git/markers.d.ts.map +1 -0
  33. package/lib/commands/apps/git/markers.js +133 -0
  34. package/lib/commands/apps/git/markers.js.map +1 -0
  35. package/lib/commands/apps/git/mode.d.ts +24 -0
  36. package/lib/commands/apps/git/mode.d.ts.map +1 -0
  37. package/lib/commands/apps/git/mode.js +102 -0
  38. package/lib/commands/apps/git/mode.js.map +1 -0
  39. package/lib/commands/apps/git/platform-source.d.ts +18 -0
  40. package/lib/commands/apps/git/platform-source.d.ts.map +1 -0
  41. package/lib/commands/apps/git/platform-source.js +151 -0
  42. package/lib/commands/apps/git/platform-source.js.map +1 -0
  43. package/lib/commands/apps/git/preflight.d.ts +21 -0
  44. package/lib/commands/apps/git/preflight.d.ts.map +1 -0
  45. package/lib/commands/apps/git/preflight.js +130 -0
  46. package/lib/commands/apps/git/preflight.js.map +1 -0
  47. package/lib/commands/apps/git/push.d.ts +29 -0
  48. package/lib/commands/apps/git/push.d.ts.map +1 -0
  49. package/lib/commands/apps/git/push.js +138 -0
  50. package/lib/commands/apps/git/push.js.map +1 -0
  51. package/lib/commands/apps/git/remote.d.ts +7 -0
  52. package/lib/commands/apps/git/remote.d.ts.map +1 -0
  53. package/lib/commands/apps/git/remote.js +48 -0
  54. package/lib/commands/apps/git/remote.js.map +1 -0
  55. package/lib/commands/apps/git/run-git.d.ts +17 -0
  56. package/lib/commands/apps/git/run-git.d.ts.map +1 -0
  57. package/lib/commands/apps/git/run-git.js +61 -0
  58. package/lib/commands/apps/git/run-git.js.map +1 -0
  59. package/lib/commands/apps/git/types.d.ts +99 -0
  60. package/lib/commands/apps/git/types.d.ts.map +1 -0
  61. package/lib/commands/apps/git/types.js +17 -0
  62. package/lib/commands/apps/git/types.js.map +1 -0
  63. package/lib/commands/apps/index.d.ts +2 -0
  64. package/lib/commands/apps/index.d.ts.map +1 -1
  65. package/lib/commands/apps/index.js +3 -0
  66. package/lib/commands/apps/index.js.map +1 -1
  67. package/lib/commands/apps/init.d.ts.map +1 -1
  68. package/lib/commands/apps/init.js +19 -3
  69. package/lib/commands/apps/init.js.map +1 -1
  70. package/lib/commands/apps/register.d.ts.map +1 -1
  71. package/lib/commands/apps/register.js +23 -4
  72. package/lib/commands/apps/register.js.map +1 -1
  73. package/lib/commands/apps/source-workflow.d.ts +32 -0
  74. package/lib/commands/apps/source-workflow.d.ts.map +1 -0
  75. package/lib/commands/apps/source-workflow.js +180 -0
  76. package/lib/commands/apps/source-workflow.js.map +1 -0
  77. package/lib/commands/apps/sync.d.ts.map +1 -1
  78. package/lib/commands/apps/sync.js +13 -8
  79. package/lib/commands/apps/sync.js.map +1 -1
  80. package/lib/docs/cli/app-management.md +114 -6
  81. package/lib/docs/index.md +1 -1
  82. package/package.json +1 -1
@@ -0,0 +1,180 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { configureManagedOrigin, createPlatformSourceApi, detectSourceMode, ensurePendingSourceMarker, inspectGitRepository, ManagedGitError, pushAllLocalRefsAtomic, pushCurrentBranchSafe, readSourceMarker, requireManagedGitPreflight, writeManagedSourceMarker, } from './git/index.js';
11
+ function platformStatus(status) {
12
+ return typeof status === 'string' ? null : status;
13
+ }
14
+ function pushManagedRepository(options_1, remote_1) {
15
+ return __awaiter(this, arguments, void 0, function* (options, remote, requireMainBranch = false, upload = 'main') {
16
+ var _a, _b;
17
+ const appDir = (_a = options.appDir) !== null && _a !== void 0 ? _a : process.cwd();
18
+ if (options.push) {
19
+ return options.push({
20
+ appDir,
21
+ expectedOriginRemote: remote,
22
+ requireMainBranch,
23
+ upload,
24
+ });
25
+ }
26
+ const preflight = yield requireManagedGitPreflight({
27
+ appDir,
28
+ expectedOriginRemote: remote,
29
+ requireMainBranch,
30
+ });
31
+ yield ((_b = options.configureOrigin) !== null && _b !== void 0 ? _b : configureManagedOrigin)(preflight.repo.root, remote, options.appId);
32
+ const push = upload === 'all_refs' ? pushAllLocalRefsAtomic : pushCurrentBranchSafe;
33
+ return push({
34
+ appDir,
35
+ expectedOriginRemote: remote,
36
+ requireMainBranch,
37
+ upload,
38
+ });
39
+ });
40
+ }
41
+ function validateLocalManagedMarker(appDir, appId) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const repo = yield inspectGitRepository(appDir);
44
+ if (!repo)
45
+ return;
46
+ const marker = readSourceMarker(repo.root);
47
+ if ((marker === null || marker === void 0 ? void 0 : marker.state) === 'managed' && marker.appId !== appId) {
48
+ throw new ManagedGitError('APP_ID_MISMATCH', [
49
+ 'The local managed-source marker does not match bkper.yaml.',
50
+ `Config App ID: ${appId}`,
51
+ `Marker App ID: ${marker.appId}`,
52
+ 'Use the clone that belongs to this App or repair the local marker intentionally.',
53
+ ].join('\n'));
54
+ }
55
+ });
56
+ }
57
+ /**
58
+ * Integrates managed activation and source pushes into direct Core metadata sync.
59
+ * Core remains the metadata authority; Artifacts pushes never deploy.
60
+ */
61
+ export function syncManagedAppSource(options) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ var _a, _b, _c, _d;
64
+ const appDir = (_a = options.appDir) !== null && _a !== void 0 ? _a : process.cwd();
65
+ const api = (_b = options.api) !== null && _b !== void 0 ? _b : createPlatformSourceApi();
66
+ const statusResult = yield api.getStatus(options.appId);
67
+ const status = platformStatus(statusResult);
68
+ const decision = yield detectSourceMode({
69
+ appDir,
70
+ appId: options.appId,
71
+ platformStatus: status,
72
+ coreAppExists: options.coreAppExists,
73
+ featureDisabled: statusResult === 'feature_disabled',
74
+ });
75
+ const action = options.coreAppExists ? 'updated' : 'created';
76
+ if (decision.mode === 'external') {
77
+ yield options.syncCore(action);
78
+ return { id: options.appId, action };
79
+ }
80
+ yield validateLocalManagedMarker(appDir, options.appId);
81
+ if (statusResult === 'feature_disabled') {
82
+ throw new ManagedGitError('MANAGED_SOURCE_UNAVAILABLE', 'This repository has a managed-source marker, but managed source is disabled. Retry when the Platform feature is available.');
83
+ }
84
+ if (decision.mode === 'activate_managed' || decision.reason === 'pending_marker') {
85
+ const preflight = yield requireManagedGitPreflight({
86
+ appDir,
87
+ requireMainBranch: true,
88
+ });
89
+ const upload = (_c = decision.upload) !== null && _c !== void 0 ? _c : 'main';
90
+ const pending = ensurePendingSourceMarker(preflight.repo.root, upload);
91
+ console.log(upload === 'all_refs'
92
+ ? 'Enabling Bkper-managed source and uploading local branches and tags...'
93
+ : 'Enabling Bkper-managed source and uploading committed main...');
94
+ yield options.syncCore(action);
95
+ const activation = yield api.activate(options.appId, pending.activationId);
96
+ if (activation.source.appId !== options.appId) {
97
+ throw new ManagedGitError('APP_ID_MISMATCH', 'Managed source activation returned a different App ID.');
98
+ }
99
+ yield ((_d = options.configureOrigin) !== null && _d !== void 0 ? _d : configureManagedOrigin)(preflight.repo.root, activation.source.remote, options.appId);
100
+ yield pushManagedRepository(options, activation.source.remote, true, pending.upload);
101
+ writeManagedSourceMarker(preflight.repo.root, options.appId, activation.source.remote);
102
+ return { id: options.appId, action };
103
+ }
104
+ if ((status === null || status === void 0 ? void 0 : status.mode) !== 'managed') {
105
+ throw new ManagedGitError('MANAGED_SOURCE_UNAVAILABLE', 'The local repository is managed, but the Platform record is not visible yet. Retry the sync.');
106
+ }
107
+ if (status.appId !== options.appId) {
108
+ throw new ManagedGitError('APP_ID_MISMATCH', 'Platform managed source does not match the local App ID.');
109
+ }
110
+ const pushed = yield pushManagedRepository(options, status.remote);
111
+ const repo = yield inspectGitRepository(appDir);
112
+ if (repo)
113
+ writeManagedSourceMarker(repo.root, options.appId, status.remote);
114
+ yield options.syncCore(action);
115
+ return { id: options.appId, action };
116
+ });
117
+ }
118
+ /**
119
+ * Pushes managed source before the caller reads and uploads existing local build output.
120
+ * External Apps remain source-less and retain direct-upload behavior.
121
+ */
122
+ export function prepareManagedDeploySource(options) {
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ var _a, _b;
125
+ const appDir = (_a = options.appDir) !== null && _a !== void 0 ? _a : process.cwd();
126
+ const api = (_b = options.api) !== null && _b !== void 0 ? _b : createPlatformSourceApi();
127
+ let statusResult;
128
+ try {
129
+ statusResult = yield api.getStatus(options.appId);
130
+ }
131
+ catch (error) {
132
+ if (error instanceof ManagedGitError && error.code === 'AUTHENTICATION_REQUIRED') {
133
+ const repo = yield inspectGitRepository(appDir);
134
+ const marker = repo ? readSourceMarker(repo.root) : null;
135
+ if (!marker)
136
+ return undefined;
137
+ }
138
+ throw error;
139
+ }
140
+ if (statusResult === 'feature_disabled' || statusResult === 'app_not_found') {
141
+ const repo = yield inspectGitRepository(appDir);
142
+ const marker = repo ? readSourceMarker(repo.root) : null;
143
+ if (marker) {
144
+ throw new ManagedGitError('MANAGED_SOURCE_UNAVAILABLE', statusResult === 'feature_disabled'
145
+ ? 'This repository is managed, but managed source is disabled in this Platform environment.'
146
+ : 'This repository is managed, but its Platform linkage is not visible. Retry the deployment.');
147
+ }
148
+ return undefined;
149
+ }
150
+ const decision = yield detectSourceMode({
151
+ appDir,
152
+ appId: options.appId,
153
+ platformStatus: statusResult,
154
+ coreAppExists: true,
155
+ });
156
+ if (decision.mode === 'external' || decision.mode === 'activate_managed') {
157
+ return undefined;
158
+ }
159
+ if (decision.reason === 'pending_marker') {
160
+ throw new ManagedGitError('MANAGED_SOURCE_UNAVAILABLE', 'Managed source activation is pending. Run `bkper app sync` to finish uploading source before deploying.');
161
+ }
162
+ yield validateLocalManagedMarker(appDir, options.appId);
163
+ if (statusResult.mode !== 'managed') {
164
+ throw new ManagedGitError('MANAGED_SOURCE_UNAVAILABLE', 'Managed source linkage is not visible yet. Run `bkper app sync` or retry the deployment.');
165
+ }
166
+ if (statusResult.appId !== options.appId) {
167
+ throw new ManagedGitError('APP_ID_MISMATCH', 'Platform managed source does not match the local App ID.');
168
+ }
169
+ const pushed = yield pushManagedRepository(options, statusResult.remote);
170
+ const repo = yield inspectGitRepository(appDir);
171
+ if (repo)
172
+ writeManagedSourceMarker(repo.root, options.appId, statusResult.remote);
173
+ return {
174
+ mode: 'managed',
175
+ declaredBranch: pushed.branch,
176
+ commitSha: pushed.head,
177
+ };
178
+ });
179
+ }
180
+ //# sourceMappingURL=source-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-workflow.js","sourceRoot":"","sources":["../../../src/commands/apps/source-workflow.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/commands/apps/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAc,MAAM,UAAU,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;GAIG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAI9C;AAED;;;;GAIG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAI9C;AAED;;;;GAIG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CA+BnD"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/commands/apps/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAc,MAAM,UAAU,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;;;;GAIG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAI9C;AAED;;;;GAIG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAI9C;AAED;;;;GAIG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAmCnD"}
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { BkperError } from 'bkper-js';
11
11
  import { getBkperInstance } from '../../bkper-factory.js';
12
12
  import { createConfiguredApp } from './config.js';
13
+ import { syncManagedAppSource } from './source-workflow.js';
13
14
  /**
14
15
  * Creates a new app from the configuration in the current directory.
15
16
  *
@@ -63,14 +64,18 @@ export function syncApp() {
63
64
  throw err;
64
65
  }
65
66
  }
66
- if (exists) {
67
- yield app.update();
68
- return { id: appId, action: 'updated' };
69
- }
70
- else {
71
- yield app.create();
72
- return { id: appId, action: 'created' };
73
- }
67
+ return syncManagedAppSource({
68
+ appId,
69
+ coreAppExists: exists,
70
+ syncCore: (action) => __awaiter(this, void 0, void 0, function* () {
71
+ if (action === 'updated') {
72
+ yield app.update();
73
+ }
74
+ else {
75
+ yield app.create();
76
+ }
77
+ }),
78
+ });
74
79
  });
75
80
  }
76
81
  //# sourceMappingURL=sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/commands/apps/sync.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAO,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;GAIG;AACH,MAAM,UAAgB,SAAS;;QAC3B,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACtB,CAAC;CAAA;AAED;;;;GAIG;AACH,MAAM,UAAgB,SAAS;;QAC3B,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACtB,CAAC;CAAA;AAED;;;;GAIG;AACH,MAAM,UAAgB,OAAO;;QACzB,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;QAE1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACxD,CAAC;QAED,sBAAsB;QACtB,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACD,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,GAAG,IAAI,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBAChD,iCAAiC;gBACjC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gBAC/C,MAAM,GAAG,KAAK,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,CAAC;YACd,CAAC;QACL,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC5C,CAAC;IACL,CAAC;CAAA"}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/commands/apps/sync.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAO,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAgB,SAAS;;QAC3B,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACtB,CAAC;CAAA;AAED;;;;GAIG;AACH,MAAM,UAAgB,SAAS;;QAC3B,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACtB,CAAC;CAAA;AAED;;;;GAIG;AACH,MAAM,UAAgB,OAAO;;QACzB,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;QAE1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACxD,CAAC;QAED,sBAAsB;QACtB,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACD,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,GAAG,IAAI,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBAChD,iCAAiC;gBACjC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gBAC/C,MAAM,GAAG,KAAK,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,CAAC;YACd,CAAC;QACL,CAAC;QAED,OAAO,oBAAoB,CAAC;YACxB,KAAK;YACL,aAAa,EAAE,MAAM;YACrB,QAAQ,EAAE,CAAM,MAAM,EAAC,EAAE;gBACrB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACvB,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACJ,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;gBACvB,CAAC;YACL,CAAC,CAAA;SACJ,CAAC,CAAC;IACP,CAAC;CAAA"}
@@ -7,6 +7,41 @@ Build, deploy, and manage Bkper apps using the `bkper` CLI.
7
7
 
8
8
  ---
9
9
 
10
+ ## Source control modes
11
+
12
+ Bkper selects source mode without changing the local-build deployment model:
13
+
14
+ - **Managed source:** `bkper app sync` activates private Bkper-managed Git for a new or existing App when `bkper.yaml` is at the root of a standalone Git repository, the current clean committed branch is `main`, and no Git remote exists. Bkper configures the managed repository as `origin`. New Apps initially upload `main`; existing Apps atomically upload all local branches and tags.
15
+ - **External source:** an App keeps direct sync/deploy behavior when it has an external Git remote, is nested in a monorepo, or is not rooted at `bkper.yaml`. The CLI never changes an existing external remote.
16
+
17
+ To opt out, keep a GitHub, GitLab, or other provider remote configured. Managed mode is sticky after activation; adding another remote later does not change it, and Artifacts remains `origin`. The App listing `repoUrl` metadata does not select source mode.
18
+
19
+ Source and deployment remain separate. `git push` stores source only and **never deploys**. `bkper app sync` pushes managed source before syncing local metadata. `bkper app deploy` pushes managed source, verifies that the exact commit exists in the linked repository, and then uploads the existing local `dist/server` and optional `dist/client` output. Builds remain local and explicit; Bkper does not claim reproducible remote CI or prove that the local bundle was built from the declared commit. Source linkage is best-effort provenance for already-authorized developers.
20
+
21
+ CLI-managed pushes are clean-tree and fast-forward-only. The CLI never commits, merges, rebases, force-pushes, resets, or discards files. Authorized developers may use ordinary Git commands, including an intentional force-push, but a push still never deploys.
22
+
23
+ Configured App developers, including matches such as `*@example.com`, can read and modify private managed source under the existing owner/developer policy. App users and Book collaborators do not receive source access unless they also satisfy that developer policy. Repository credentials are exact URL/path-scoped, noninteractive, and valid for five minutes; they are never persisted by Bkper.
24
+
25
+ ### Migrate from an external Git provider
26
+
27
+ Source changes remain the user or coding agent's responsibility; the CLI never removes or renames provider remotes. Before migration, verify that `main` is clean and committed, the provider has the latest source, and every desired provider-only branch and tag is available locally. A coding agent must show the exact mutating commands and obtain explicit user approval before continuing.
28
+
29
+ Inspect first:
30
+
31
+ ```bash
32
+ git status --short --branch
33
+ git remote -v
34
+ ```
35
+
36
+ After approval, remove every external remote and sync. For a repository whose only external remote is `origin`:
37
+
38
+ ```bash
39
+ git remote remove origin
40
+ bkper app sync
41
+ ```
42
+
43
+ Sync preserves the existing App identity, activates managed source, configures it as `origin`, and atomically uploads all local branches and tags. If that upload fails, the pending marker makes the next `bkper app sync` retry the complete upload. `bkper app deploy` never activates migration.
44
+
10
45
  ## Verification Workflow
11
46
 
12
47
  When scaffolding, developing, or deploying an app, verify each step before proceeding. This prevents broken deployments and silent failures.
@@ -18,13 +53,14 @@ bkper app init my-app
18
53
  cd my-app
19
54
  ```
20
55
 
21
- `bkper app init <name>` creates and scaffolds `./<name>` using the same value as the app id. Run `bkper app init` with no name inside an existing empty or VCS-only directory to use the current folder name as the app id.
56
+ `bkper app init <name>` creates and scaffolds `./<name>` using the same value as the app id. Run `bkper app init` with no name inside an existing empty or VCS-only directory to use the current folder name as the app id. Init initializes Git on `main` when needed, but does not create commits.
22
57
 
23
58
  Verify:
24
59
 
25
60
  - `client/` and `server/` exist
26
61
  - `bkper.yaml` has `id`, `name`, `description`, and `developers`
27
62
  - `package.json` scripts include `dev` and `build`
63
+ - `.git` exists on branch `main` with no automatic commit
28
64
 
29
65
  ### 2. Develop
30
66
 
@@ -53,14 +89,24 @@ Verify:
53
89
 
54
90
  ### 4. Sync & Deploy
55
91
 
92
+ Commit source before the first eligible managed sync:
93
+
56
94
  ```bash
57
- bkper app sync && bkper app deploy
95
+ git add .
96
+ git commit -m "Initial app"
97
+ bkper app sync
98
+ npm run build
99
+ bkper app deploy
58
100
  ```
59
101
 
102
+ For a managed App, sync and deploy safely push the current committed branch. For an external App, both commands preserve direct local metadata and bundle upload behavior without changing remotes.
103
+
60
104
  Verify:
61
105
 
62
106
  - `bkper app status` shows the deployed version
107
+ - managed status shows the declared branch and exact verified SHA
63
108
  - URLs in `bkper.yaml` match the deployed domain (`https://{appId}.bkper.app`)
109
+ - an ordinary `git push` did not deploy anything
64
110
 
65
111
  #### Preview testing with menu and events
66
112
 
@@ -139,6 +185,66 @@ bkper app status
139
185
 
140
186
  ---
141
187
 
188
+ ## Clone managed source
189
+
190
+ Clone an existing managed App explicitly:
191
+
192
+ ```bash
193
+ bkper app clone <appId> [path]
194
+ cd <path-or-appId>
195
+ bun install
196
+ ```
197
+
198
+ Clone authenticates with Bkper, uses a temporary sibling directory, validates the cloned App ID, and atomically installs the destination. It never installs dependencies or executes repository lifecycle scripts. External-source Apps must be cloned from their configured provider instead.
199
+
200
+ If Git authentication fails:
201
+
202
+ 1. Run `bkper auth login` when the Bkper session is missing or expired.
203
+ 2. Retry the Git operation; a five-minute repository credential is minted automatically.
204
+ 3. If the managed `origin` is missing or incorrect, inspect `git remote -v` and use a fresh `bkper app clone <appId>` as the safe reference. Never replace an unrelated external remote automatically.
205
+ 4. Request App owner/developer access when Platform denies source access. Domain-pattern developers have the same private source read/write capability.
206
+
207
+ The helper command is intentionally `bkper app git-credential <appId> [operation]`. It is internal Git plumbing, not a root `git` command or an `app git` group.
208
+
209
+ ## Managed Git preflight recovery
210
+
211
+ Managed sync and deploy require `bkper.yaml` at the Git root, an attached branch, committed `HEAD`, and a clean tree. Ignored build output such as `dist/` is allowed.
212
+
213
+ | Failure | Safe recovery |
214
+ | --- | --- |
215
+ | No Git repository | For a standalone App, run `git init -b main`, review files, commit, and retry. An eligible new or existing App activates managed source on sync when no remote exists. |
216
+ | `bkper.yaml` below Git root | Keep the monorepo/external workflow; managed monorepos are not supported. |
217
+ | No commits | Review, then run `git add .` and `git commit -m "Initial app"`. |
218
+ | Detached `HEAD` | Attach a branch with `git switch -c <branch>`; use `main` for first activation. |
219
+ | First activation is not on `main` | Switch to the existing `main` branch. The CLI does not rename or rewrite branches. |
220
+ | Staged changes | Inspect `git diff --cached`; commit them or intentionally unstage them before retrying. |
221
+ | Modified tracked files | Inspect `git diff`; commit or intentionally restore them before retrying. |
222
+ | Non-ignored untracked files | Inspect `git status`; commit, ignore, or intentionally remove them before retrying. |
223
+ | Missing or incorrect managed `origin` | Inspect `git remote -v`; compare with a fresh managed clone. Do not overwrite an external remote. |
224
+ | Authentication or expired credential | Run `bkper auth login` if needed, then retry the Git operation for a new five-minute token. |
225
+ | Remote branch ahead or divergent | Run `git fetch origin <branch>` and inspect `git log --oneline --left-right HEAD...origin/<branch>`; merge or rebase by your own choice, then push and retry. The CLI never force-resolves divergence. |
226
+ | App ID or repository mismatch | Stop and use the clone/config belonging to the requested App; do not rewrite repository identity. |
227
+ | Managed record temporarily missing | Retry sync/deploy. A managed marker never silently downgrades to external mode after a transient KV miss. |
228
+ | Exact commit missing | Ensure the current clean commit was pushed to the registered managed `origin`, then retry. |
229
+
230
+ ## Roll back a managed deployment
231
+
232
+ There is no hidden rollback ref, retained build archive, or automatic rollback API. Create an ordinary attached rollback branch at the selected committed source, build locally, and deploy explicitly:
233
+
234
+ ```bash
235
+ git switch -c rollback/<name> <older-commit>
236
+ bun run build
237
+ bkper app deploy --preview
238
+ # verify, then optionally deploy production
239
+ bkper app deploy
240
+ ```
241
+
242
+ The rollback branch is pushed normally. Preview remains optional; production does not require promotion from preview.
243
+
244
+ `bkper app undeploy` removes only the selected runtime and optional runtime data. It never deletes managed source.
245
+
246
+ ---
247
+
142
248
  ## Install Apps on Books
143
249
 
144
250
  ```bash
@@ -425,11 +531,13 @@ Inside the interactive agent:
425
531
 
426
532
  ### App Lifecycle
427
533
 
428
- - `app init [name]` - Scaffold a new app from the template. With `name`, creates `./<name>` and uses it as the app id. Without `name`, initializes the current directory and derives the app id from the folder name.
534
+ - `app init [name]` - Scaffold a new app from the template. With `name`, creates `./<name>` and uses it as the app id. Without `name`, initializes the current directory and derives the app id from the folder name. Initializes Git on `main` when the target is not already a repository, without staging or committing files.
535
+ - `app clone <appId> [path]` - Clone a Bkper-managed App source repository. Does not install dependencies; run `bun install` explicitly afterward. External-source Apps must be cloned from their provider instead.
536
+ - `app git-credential <appId> [operation]` - Internal noninteractive Git credential helper for managed Artifacts source. Generated repository config pins the App ID and exact remote URL/path; Git appends `get`, `store`, or `erase`. Never persists tokens.
429
537
  - `app list` - List all apps you have access to
430
- - `app sync` - Sync [bkper.yaml][bkper.yaml reference] configuration (URLs, description) to Bkper API
538
+ - `app sync` - Sync [bkper.yaml][bkper.yaml reference] configuration. For an eligible standalone repository with no remote, activate managed source for a new or existing App; existing migrations atomically upload all local branches and tags. If already managed, cleanly fast-forward-push the current committed branch first.
431
539
  - `app build` - Build the server Worker bundle for deployment
432
- - `app deploy` - Deploy built artifacts to Cloudflare Workers for Platforms
540
+ - `app deploy` - For managed Apps, cleanly fast-forward-push and verify the current commit, then explicitly deploy the existing local build. External Apps keep direct upload behavior.
433
541
  - `-p, --preview` - Deploy to preview environment
434
542
  - `app status` - Show deployment status
435
543
  - `app logs [appId]` - View recent app logs. When `appId` is omitted, the app id is read from local app config.
@@ -449,7 +557,7 @@ Inside the interactive agent:
449
557
  - `--sp, --server-port <port>` - Server simulation port (default: `8787`)
450
558
  - `--cp, --client-port <port>` - Client dev server port for local static assets (default: `5173`)
451
559
 
452
- > **Note:** `sync` and `deploy` are independent operations. Use `sync` to update your app's URLs in Bkper (required for webhooks and menu integration). Use `deploy` to push code to Cloudflare. For a typical deployment workflow, run both: `bkper app sync && bkper app deploy`
560
+ > **Note:** `sync` and `deploy` are independent explicit operations. `sync` updates App metadata and, for managed Apps, safely pushes committed source. `deploy` uploads an existing local build and never runs a build command. An ordinary Git push never deploys.
453
561
 
454
562
  ### App Installation
455
563
 
package/lib/docs/index.md CHANGED
@@ -6,7 +6,7 @@ For Bkper data, accounting, reporting, tax, or financial-flow tasks, read `core/
6
6
 
7
7
  - `core/core-concepts.md` — canonical Bkper data model: resources, movements, balances, accounts, groups, books, transactions, properties, and the zero-sum invariant.
8
8
  - `cli/data-management.md` — CLI reference for managing financial data and files: books, accounts, groups, files, transactions, per-account balance queries, query operators (on:, after:, before:, account:, group:), output formats (table/json/csv), human-review Bkper UI links, batch operations via stdin/piping, collections.
9
- - `cli/app-management.md` — CLI reference for building and deploying Bkper apps: dev/build/deploy workflow, app install/uninstall, secrets management, app logs, bkper.yaml configuration reference (identity, branding, events, menu integration, deployment).
9
+ - `cli/app-management.md` — CLI reference for building and deploying Bkper apps: init/git clone/credential helpers, dev/build/deploy workflow, app install/uninstall, secrets management, app logs, bkper.yaml configuration reference (identity, branding, events, menu integration, deployment).
10
10
  - `apps/app-building.md` — Full app-building reference: single Worker app architecture (`client/` + `server/`), development loop, `/api/*` routes, `/events` handlers, deployment patterns, the Bkper Platform, and self-hosted alternatives. Includes authentication patterns for web clients (`@bkper/web-auth`), server API routes (`Authorization: Bearer` on `/api/*` with outbound auth injection), platform event handlers (`new Bkper()` with outbound auth injection), and local development.
11
11
  - `reporting/financial-statements.md` — Deterministic reporting principles and Bkper query semantics for balance sheet and P&L: trusted routes, root reporting groups, permanent vs period date rules, and provisional query patterns.
12
12
  - `reporting/taxes.md` — Deterministic tax reporting principles: trusted routes, external tax-rule loading/discovery, user-approved tax-relevant groups/accounts, period activity queries, explicit jurisdiction assumptions, and provisional query patterns.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bkper",
3
- "version": "4.24.2",
3
+ "version": "4.25.0",
4
4
  "description": "Command line client for Bkper",
5
5
  "bin": {
6
6
  "bkper": "./lib/cli.js"