@bakers-build/addon-info 0.0.0-stage → 0.1.0-next.42

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 keytec GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
- # Temporary Holding Version
1
+ # @bakers-build/addon-info
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ bakers info: resolved project and workspace context for an agent the conductor did not start (BB-495).
4
+
5
+ Part of the bakers.build CLI. Install the meta package `@bakers-build/bakers` to get the `bakers` CLI with all addons. Source: https://git.key-tec.de/bakers-build/bakers-build (bakers-cli/).
@@ -0,0 +1,5 @@
1
+ import type { BbCommandPlugin } from '@bakers-build/core';
2
+ declare const infoCommand: BbCommandPlugin;
3
+ export default infoCommand;
4
+ export type { BbInfoResult, ResolveBbInfoOptions } from './info.js';
5
+ export { resolveBbInfo } from './info.js';
@@ -0,0 +1,27 @@
1
+ import { resolveBbInfo } from './info.js';
2
+ const infoCommand = {
3
+ kind: 'command',
4
+ name: 'info',
5
+ describe: 'print the resolved project and workspace context as JSON',
6
+ register(program, host) {
7
+ program
8
+ .command('info')
9
+ .description('Print the resolved project and workspace context (BB-495) as JSON')
10
+ .option('--config <path>', 'connection config path')
11
+ .option('--connection <id>', 'named connection from ~/.bakers/connections')
12
+ .action(async (options) => {
13
+ const result = await resolveBbInfo({
14
+ host,
15
+ ...(options.config !== undefined
16
+ ? { explicitConfig: options.config }
17
+ : {}),
18
+ ...(options.connection !== undefined
19
+ ? { connection: options.connection }
20
+ : {}),
21
+ });
22
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
23
+ });
24
+ },
25
+ };
26
+ export default infoCommand;
27
+ export { resolveBbInfo } from './info.js';
@@ -0,0 +1,31 @@
1
+ import { type BbCommandHost } from '@bakers-build/core';
2
+ /**
3
+ * The resolved project/workspace context (BB-495). A value that cannot be
4
+ * resolved is `null` (or `[]` for `workspace_ids`), never omitted — the shape
5
+ * is always stable, which is what lets an unattended agent parse it without a
6
+ * presence check per key.
7
+ */
8
+ export interface BbInfoResult {
9
+ project: string | null;
10
+ project_id: string | null;
11
+ workspace: string | null;
12
+ workspace_id: string | null;
13
+ workspace_ids: string[];
14
+ }
15
+ export interface ResolveBbInfoOptions {
16
+ host: BbCommandHost;
17
+ /** Defaults to `process.env`; injectable for tests. */
18
+ env?: Record<string, string | undefined>;
19
+ cwd?: string;
20
+ explicitConfig?: string;
21
+ connection?: string;
22
+ }
23
+ /**
24
+ * Resolve the five context values BB-495 D3 gives an agent: read the
25
+ * reserved env vars the conductor set at dispatch first (the fast path), and
26
+ * for any that is unset, resolve it live over the connection — never
27
+ * prompting, never writing to disk. This is what `bakers info` covers: the
28
+ * agent that was not started by the conductor, and the shell where nothing
29
+ * is set.
30
+ */
31
+ export declare function resolveBbInfo(opts: ResolveBbInfoOptions): Promise<BbInfoResult>;
@@ -0,0 +1,97 @@
1
+ import { resolveBbProjectContext } from '@bakers-build/conductor/contract';
2
+ import { readBbProjectSelection } from '@bakers-build/conductor/project-context';
3
+ import { createBbConnectionClient, discoverBbWorkspaces, loadReadyBbConnection, resolveConfigPath, } from '@bakers-build/core';
4
+ /**
5
+ * Resolve the five context values BB-495 D3 gives an agent: read the
6
+ * reserved env vars the conductor set at dispatch first (the fast path), and
7
+ * for any that is unset, resolve it live over the connection — never
8
+ * prompting, never writing to disk. This is what `bakers info` covers: the
9
+ * agent that was not started by the conductor, and the shell where nothing
10
+ * is set.
11
+ */
12
+ export async function resolveBbInfo(opts) {
13
+ const env = opts.env ?? process.env;
14
+ let project = env.BB_PROJECT ?? null;
15
+ let projectId = env.BB_PROJECT_ID ?? null;
16
+ let workspace = env.BB_WORKSPACE ?? null;
17
+ let workspaceId = env.BB_WORKSPACE_ID ?? null;
18
+ let workspaceIds = env.BB_WORKSPACE_IDS
19
+ ? env.BB_WORKSPACE_IDS.split(',').filter((id) => id !== '')
20
+ : [];
21
+ const loadOpts = {
22
+ ...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
23
+ explicit: opts.explicitConfig,
24
+ ...(opts.connection ? { connection: opts.connection } : {}),
25
+ };
26
+ // Resolving the project layer is part of the same optional read as parsing
27
+ // it: standing outside any checkout is not an error here, it is the ordinary
28
+ // situation of someone who has a machine and a connection and no project
29
+ // yet. Both the failed walk and an absent file report ENOENT, so the
30
+ // connection-derived keys below still answer.
31
+ let configured;
32
+ try {
33
+ configured = readBbProjectSelection(resolveConfigPath(undefined, opts.cwd ?? process.cwd()));
34
+ }
35
+ catch (error) {
36
+ if (error.code !== 'ENOENT')
37
+ throw error;
38
+ }
39
+ if (project === null && configured)
40
+ project = configured.project;
41
+ if (workspace === null && configured?.workspace)
42
+ workspace = configured.workspace;
43
+ if (configured?.workspace)
44
+ loadOpts.workspaceSelector = configured.workspace;
45
+ if (configured && !configured.workspace)
46
+ loadOpts.workspaceIdOverride = '';
47
+ let connection = null;
48
+ if (workspace === null ||
49
+ workspaceId === null ||
50
+ workspaceIds.length === 0 ||
51
+ (projectId === null && project !== null)) {
52
+ try {
53
+ connection = await loadReadyBbConnection(opts.host, loadOpts);
54
+ if (workspaceId === null)
55
+ workspaceId = connection.workspace_id ?? null;
56
+ if (workspace === null && connection.workspace_id) {
57
+ try {
58
+ const client = await createBbConnectionClient(connection);
59
+ const ws = await client.resource('bb_workspace', connection.workspace_id);
60
+ workspace = ws.attr('name') ?? null;
61
+ }
62
+ catch {
63
+ // Leave workspace null — the connection resolved but the resource
64
+ // read did not; workspace_id/workspace_ids may still be usable.
65
+ }
66
+ }
67
+ if (workspaceIds.length === 0) {
68
+ try {
69
+ const choices = await discoverBbWorkspaces(connection);
70
+ workspaceIds = choices.map((c) => c.id);
71
+ }
72
+ catch {
73
+ // Leave workspace_ids empty — not a hard failure for the other keys.
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ // No usable connection — every connection-derived key stays null/empty.
79
+ }
80
+ }
81
+ if (projectId === null && configured) {
82
+ connection ??= await loadReadyBbConnection(opts.host, loadOpts);
83
+ const client = await createBbConnectionClient(connection);
84
+ const context = await resolveBbProjectContext(client, configured);
85
+ projectId = context.projectId;
86
+ project = context.project;
87
+ workspaceId = context.workspaceId;
88
+ workspace = context.workspace;
89
+ }
90
+ return {
91
+ project,
92
+ project_id: projectId,
93
+ workspace,
94
+ workspace_id: workspaceId,
95
+ workspace_ids: workspaceIds,
96
+ };
97
+ }
@@ -0,0 +1,2 @@
1
+ import type { BbPreset } from '@bakers-build/core';
2
+ export declare const commands: BbPreset['commands'];
@@ -0,0 +1,8 @@
1
+ export const commands = (acc) => [
2
+ ...acc,
3
+ {
4
+ name: 'info',
5
+ plugin: '@bakers-build/addon-info',
6
+ describe: 'print the resolved project and workspace context as JSON',
7
+ },
8
+ ];
package/package.json CHANGED
@@ -1,6 +1,29 @@
1
1
  {
2
2
  "name": "@bakers-build/addon-info",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0-next.42",
4
+ "description": "bakers info: resolved project and workspace context for an agent the conductor did not start (BB-495).",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": "./dist/src/index.js",
9
+ "./preset": "./dist/src/preset.js"
10
+ },
11
+ "files": [
12
+ "dist/src"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://git.key-tec.de/bakers-build/bakers-build.git",
20
+ "directory": "bakers-cli/addons/info"
21
+ },
22
+ "dependencies": {
23
+ "commander": "^12.1.0"
24
+ },
25
+ "peerDependencies": {
26
+ "@bakers-build/conductor": "^0.1.0-next.42",
27
+ "@bakers-build/core": "^0.1.0-next.42"
28
+ }
29
+ }