@markjaquith/agency 0.5.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/LICENSE +21 -0
- package/README.md +109 -0
- package/cli.ts +569 -0
- package/index.ts +1 -0
- package/package.json +65 -0
- package/src/commands/base.test.ts +198 -0
- package/src/commands/base.ts +198 -0
- package/src/commands/clean.test.ts +299 -0
- package/src/commands/clean.ts +320 -0
- package/src/commands/emit.test.ts +412 -0
- package/src/commands/emit.ts +521 -0
- package/src/commands/emitted.test.ts +226 -0
- package/src/commands/emitted.ts +57 -0
- package/src/commands/init.test.ts +311 -0
- package/src/commands/init.ts +140 -0
- package/src/commands/merge.test.ts +365 -0
- package/src/commands/merge.ts +253 -0
- package/src/commands/pull.test.ts +385 -0
- package/src/commands/pull.ts +205 -0
- package/src/commands/push.test.ts +394 -0
- package/src/commands/push.ts +346 -0
- package/src/commands/save.test.ts +247 -0
- package/src/commands/save.ts +162 -0
- package/src/commands/source.test.ts +195 -0
- package/src/commands/source.ts +72 -0
- package/src/commands/status.test.ts +489 -0
- package/src/commands/status.ts +258 -0
- package/src/commands/switch.test.ts +194 -0
- package/src/commands/switch.ts +84 -0
- package/src/commands/task-branching.test.ts +334 -0
- package/src/commands/task-edit.test.ts +141 -0
- package/src/commands/task-main.test.ts +872 -0
- package/src/commands/task.ts +712 -0
- package/src/commands/tasks.test.ts +335 -0
- package/src/commands/tasks.ts +155 -0
- package/src/commands/template-delete.test.ts +178 -0
- package/src/commands/template-delete.ts +98 -0
- package/src/commands/template-list.test.ts +135 -0
- package/src/commands/template-list.ts +87 -0
- package/src/commands/template-view.test.ts +158 -0
- package/src/commands/template-view.ts +86 -0
- package/src/commands/template.test.ts +32 -0
- package/src/commands/template.ts +96 -0
- package/src/commands/use.test.ts +87 -0
- package/src/commands/use.ts +97 -0
- package/src/commands/work.test.ts +462 -0
- package/src/commands/work.ts +193 -0
- package/src/errors.ts +17 -0
- package/src/schemas.ts +33 -0
- package/src/services/AgencyMetadataService.ts +287 -0
- package/src/services/ClaudeService.test.ts +184 -0
- package/src/services/ClaudeService.ts +91 -0
- package/src/services/ConfigService.ts +115 -0
- package/src/services/FileSystemService.ts +222 -0
- package/src/services/GitService.ts +751 -0
- package/src/services/OpencodeService.ts +263 -0
- package/src/services/PromptService.ts +183 -0
- package/src/services/TemplateService.ts +75 -0
- package/src/test-utils.ts +362 -0
- package/src/types/native-exec.d.ts +8 -0
- package/src/types.ts +216 -0
- package/src/utils/colors.ts +178 -0
- package/src/utils/command.ts +17 -0
- package/src/utils/effect.ts +281 -0
- package/src/utils/exec.ts +48 -0
- package/src/utils/paths.ts +51 -0
- package/src/utils/pr-branch.test.ts +372 -0
- package/src/utils/pr-branch.ts +473 -0
- package/src/utils/process.ts +110 -0
- package/src/utils/spinner.ts +82 -0
- package/templates/AGENCY.md +20 -0
- package/templates/AGENTS.md +11 -0
- package/templates/CLAUDE.md +3 -0
- package/templates/TASK.md +5 -0
- package/templates/opencode.json +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@markjaquith/agency",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Manages personal agents files",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Mark Jaquith",
|
|
7
|
+
"module": "index.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"bin": {
|
|
10
|
+
"agency": "cli.ts"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "bun test",
|
|
14
|
+
"format": "prettier --write .",
|
|
15
|
+
"format:check": "prettier --check .",
|
|
16
|
+
"knip": "knip --production",
|
|
17
|
+
"pushable": "./scripts/pushable",
|
|
18
|
+
"check-commit-msg": "./scripts/check-commit-msg",
|
|
19
|
+
"changeset": "changeset",
|
|
20
|
+
"version": "changeset version",
|
|
21
|
+
"release": "bun run build && changeset publish --provenance",
|
|
22
|
+
"build": "bun build cli.ts --outdir dist --target node --minify"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./index.ts",
|
|
27
|
+
"types": "./index.ts"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"index.ts",
|
|
32
|
+
"cli.ts",
|
|
33
|
+
"src",
|
|
34
|
+
"templates",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"keywords": [
|
|
39
|
+
"agents",
|
|
40
|
+
"bun",
|
|
41
|
+
"typescript",
|
|
42
|
+
"personal-agents"
|
|
43
|
+
],
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@changesets/cli": "^2.29.8",
|
|
46
|
+
"@types/bun": "latest",
|
|
47
|
+
"knip": "^5.70.1",
|
|
48
|
+
"prettier": "^3.6.2"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"typescript": "^5"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"bun": ">=1.0.0"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@effect/schema": "^0.75.5",
|
|
58
|
+
"effect": "^3.19.6",
|
|
59
|
+
"jsonc-parser": "^3.3.1",
|
|
60
|
+
"ora": "^8.1.1"
|
|
61
|
+
},
|
|
62
|
+
"trustedDependencies": [
|
|
63
|
+
"@triggi/native-exec"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach, afterEach } from "bun:test"
|
|
2
|
+
import { base } from "./base"
|
|
3
|
+
import {
|
|
4
|
+
createTempDir,
|
|
5
|
+
cleanupTempDir,
|
|
6
|
+
initGitRepo,
|
|
7
|
+
getGitConfig,
|
|
8
|
+
runTestEffect,
|
|
9
|
+
} from "../test-utils"
|
|
10
|
+
import { getBaseBranchFromMetadata, writeAgencyMetadata } from "../types"
|
|
11
|
+
|
|
12
|
+
describe("base", () => {
|
|
13
|
+
let testDir: string
|
|
14
|
+
let originalCwd: string
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
originalCwd = process.cwd()
|
|
18
|
+
testDir = await createTempDir()
|
|
19
|
+
await initGitRepo(testDir)
|
|
20
|
+
process.chdir(testDir)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
afterEach(async () => {
|
|
24
|
+
process.chdir(originalCwd)
|
|
25
|
+
await cleanupTempDir(testDir)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe("base set", () => {
|
|
29
|
+
test("sets base branch for current branch", async () => {
|
|
30
|
+
// Create a feature branch
|
|
31
|
+
await Bun.spawn(["git", "checkout", "-b", "feature"], {
|
|
32
|
+
cwd: testDir,
|
|
33
|
+
stdout: "pipe",
|
|
34
|
+
stderr: "pipe",
|
|
35
|
+
}).exited
|
|
36
|
+
|
|
37
|
+
// Create agency.json first
|
|
38
|
+
await writeAgencyMetadata(testDir, {
|
|
39
|
+
version: 1 as const,
|
|
40
|
+
template: "test",
|
|
41
|
+
injectedFiles: [],
|
|
42
|
+
createdAt: new Date().toISOString(),
|
|
43
|
+
} as any)
|
|
44
|
+
|
|
45
|
+
// Set base branch
|
|
46
|
+
await runTestEffect(
|
|
47
|
+
base({
|
|
48
|
+
subcommand: "set",
|
|
49
|
+
args: ["main"],
|
|
50
|
+
silent: true,
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// Verify it was saved
|
|
55
|
+
const savedBase = await getBaseBranchFromMetadata(testDir)
|
|
56
|
+
expect(savedBase).toBe("main")
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test("sets repository-level default base branch", async () => {
|
|
60
|
+
// Set repo-level base branch
|
|
61
|
+
await runTestEffect(
|
|
62
|
+
base({
|
|
63
|
+
subcommand: "set",
|
|
64
|
+
args: ["main"],
|
|
65
|
+
repo: true,
|
|
66
|
+
silent: true,
|
|
67
|
+
}),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
// Verify it was saved to git config
|
|
71
|
+
const savedBase = await getGitConfig("agency.baseBranch", testDir)
|
|
72
|
+
expect(savedBase).toBe("main")
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test("throws error if base branch does not exist", async () => {
|
|
76
|
+
await expect(
|
|
77
|
+
runTestEffect(
|
|
78
|
+
base({
|
|
79
|
+
subcommand: "set",
|
|
80
|
+
args: ["nonexistent"],
|
|
81
|
+
silent: true,
|
|
82
|
+
}),
|
|
83
|
+
),
|
|
84
|
+
).rejects.toThrow("does not exist")
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
describe("base get", () => {
|
|
89
|
+
test("gets base branch for current branch", async () => {
|
|
90
|
+
// Create a feature branch
|
|
91
|
+
await Bun.spawn(["git", "checkout", "-b", "feature"], {
|
|
92
|
+
cwd: testDir,
|
|
93
|
+
stdout: "pipe",
|
|
94
|
+
stderr: "pipe",
|
|
95
|
+
}).exited
|
|
96
|
+
|
|
97
|
+
// Create agency.json with base branch
|
|
98
|
+
await writeAgencyMetadata(testDir, {
|
|
99
|
+
version: 1,
|
|
100
|
+
template: "test",
|
|
101
|
+
injectedFiles: [],
|
|
102
|
+
baseBranch: "main",
|
|
103
|
+
createdAt: new Date().toISOString(),
|
|
104
|
+
} as any)
|
|
105
|
+
|
|
106
|
+
// Mock console.log to capture output
|
|
107
|
+
const logs: string[] = []
|
|
108
|
+
const originalLog = console.log
|
|
109
|
+
console.log = (...args: any[]) => logs.push(args.join(" "))
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
await runTestEffect(
|
|
113
|
+
base({
|
|
114
|
+
subcommand: "get",
|
|
115
|
+
args: [],
|
|
116
|
+
silent: false,
|
|
117
|
+
}),
|
|
118
|
+
)
|
|
119
|
+
expect(logs[0]).toBe("main")
|
|
120
|
+
} finally {
|
|
121
|
+
console.log = originalLog
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test("throws error if no base branch configured", async () => {
|
|
126
|
+
// Create a feature branch
|
|
127
|
+
await Bun.spawn(["git", "checkout", "-b", "feature"], {
|
|
128
|
+
cwd: testDir,
|
|
129
|
+
stdout: "pipe",
|
|
130
|
+
stderr: "pipe",
|
|
131
|
+
}).exited
|
|
132
|
+
|
|
133
|
+
// Create agency.json without base branch
|
|
134
|
+
await writeAgencyMetadata(testDir, {
|
|
135
|
+
version: 1,
|
|
136
|
+
template: "test",
|
|
137
|
+
injectedFiles: [],
|
|
138
|
+
createdAt: new Date().toISOString(),
|
|
139
|
+
} as any)
|
|
140
|
+
|
|
141
|
+
await expect(
|
|
142
|
+
runTestEffect(
|
|
143
|
+
base({
|
|
144
|
+
subcommand: "get",
|
|
145
|
+
args: [],
|
|
146
|
+
silent: true,
|
|
147
|
+
}),
|
|
148
|
+
),
|
|
149
|
+
).rejects.toThrow("No base branch configured")
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
describe("base command", () => {
|
|
154
|
+
test("requires subcommand", async () => {
|
|
155
|
+
await expect(
|
|
156
|
+
runTestEffect(base({ args: [], silent: true })),
|
|
157
|
+
).rejects.toThrow("Subcommand is required")
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
test("handles 'set' subcommand", async () => {
|
|
161
|
+
await Bun.spawn(["git", "checkout", "-b", "feature"], {
|
|
162
|
+
cwd: testDir,
|
|
163
|
+
stdout: "pipe",
|
|
164
|
+
stderr: "pipe",
|
|
165
|
+
}).exited
|
|
166
|
+
|
|
167
|
+
await writeAgencyMetadata(testDir, {
|
|
168
|
+
version: 1,
|
|
169
|
+
template: "test",
|
|
170
|
+
injectedFiles: [],
|
|
171
|
+
createdAt: new Date().toISOString(),
|
|
172
|
+
} as any)
|
|
173
|
+
|
|
174
|
+
await runTestEffect(
|
|
175
|
+
base({
|
|
176
|
+
subcommand: "set",
|
|
177
|
+
args: ["main"],
|
|
178
|
+
silent: true,
|
|
179
|
+
}),
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
const savedBase = await getBaseBranchFromMetadata(testDir)
|
|
183
|
+
expect(savedBase).toBe("main")
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
test("throws error for unknown subcommand", async () => {
|
|
187
|
+
await expect(
|
|
188
|
+
runTestEffect(
|
|
189
|
+
base({
|
|
190
|
+
subcommand: "unknown",
|
|
191
|
+
args: [],
|
|
192
|
+
silent: true,
|
|
193
|
+
}),
|
|
194
|
+
),
|
|
195
|
+
).rejects.toThrow("Unknown subcommand")
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
})
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Effect } from "effect"
|
|
2
|
+
import { GitService } from "../services/GitService"
|
|
3
|
+
import { setBaseBranchInMetadata, getBaseBranchFromMetadata } from "../types"
|
|
4
|
+
import highlight, { done } from "../utils/colors"
|
|
5
|
+
import {
|
|
6
|
+
createLoggers,
|
|
7
|
+
ensureGitRepo,
|
|
8
|
+
ensureBranchExists,
|
|
9
|
+
} from "../utils/effect"
|
|
10
|
+
|
|
11
|
+
interface BaseOptions {
|
|
12
|
+
subcommand?: string
|
|
13
|
+
args: string[]
|
|
14
|
+
repo?: boolean
|
|
15
|
+
silent?: boolean
|
|
16
|
+
verbose?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface BaseSetOptions {
|
|
20
|
+
baseBranch: string
|
|
21
|
+
repo?: boolean
|
|
22
|
+
silent?: boolean
|
|
23
|
+
verbose?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface BaseGetOptions {
|
|
27
|
+
repo?: boolean
|
|
28
|
+
silent?: boolean
|
|
29
|
+
verbose?: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Effect-based implementation
|
|
33
|
+
const baseSetEffect = (options: BaseSetOptions) =>
|
|
34
|
+
Effect.gen(function* () {
|
|
35
|
+
const { baseBranch, repo = false } = options
|
|
36
|
+
const { log, verboseLog } = createLoggers(options)
|
|
37
|
+
|
|
38
|
+
const git = yield* GitService
|
|
39
|
+
const gitRoot = yield* ensureGitRepo()
|
|
40
|
+
|
|
41
|
+
// Validate that the base branch exists
|
|
42
|
+
yield* ensureBranchExists(
|
|
43
|
+
gitRoot,
|
|
44
|
+
baseBranch,
|
|
45
|
+
`Base branch ${highlight.branch(baseBranch)} does not exist. Please provide a valid branch name.`,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
if (repo) {
|
|
49
|
+
// Set repository-level default base branch in git config
|
|
50
|
+
yield* git.setDefaultBaseBranchConfig(baseBranch, gitRoot)
|
|
51
|
+
log(
|
|
52
|
+
done(
|
|
53
|
+
`Set repository-level default base branch to ${highlight.branch(baseBranch)}`,
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
} else {
|
|
57
|
+
// Set branch-specific base branch in agency.json
|
|
58
|
+
const currentBranch = yield* git.getCurrentBranch(gitRoot)
|
|
59
|
+
verboseLog(`Current branch: ${highlight.branch(currentBranch)}`)
|
|
60
|
+
|
|
61
|
+
// Use Effect.tryPromise for metadata functions
|
|
62
|
+
yield* Effect.tryPromise({
|
|
63
|
+
try: () => setBaseBranchInMetadata(gitRoot, baseBranch),
|
|
64
|
+
catch: (error) =>
|
|
65
|
+
new Error(`Failed to set base branch in metadata: ${error}`),
|
|
66
|
+
})
|
|
67
|
+
log(
|
|
68
|
+
done(
|
|
69
|
+
`Set base branch to ${highlight.branch(baseBranch)} for ${highlight.branch(currentBranch)}`,
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Effect-based implementation
|
|
76
|
+
const baseGetEffect = (options: BaseGetOptions) =>
|
|
77
|
+
Effect.gen(function* () {
|
|
78
|
+
const { repo = false } = options
|
|
79
|
+
const { log, verboseLog } = createLoggers(options)
|
|
80
|
+
|
|
81
|
+
const git = yield* GitService
|
|
82
|
+
const gitRoot = yield* ensureGitRepo()
|
|
83
|
+
|
|
84
|
+
let currentBase: string | null
|
|
85
|
+
|
|
86
|
+
if (repo) {
|
|
87
|
+
// Get repository-level default base branch from git config
|
|
88
|
+
verboseLog("Reading repository-level default base branch from git config")
|
|
89
|
+
currentBase = yield* git.getDefaultBaseBranchConfig(gitRoot)
|
|
90
|
+
|
|
91
|
+
if (!currentBase) {
|
|
92
|
+
return yield* Effect.fail(
|
|
93
|
+
new Error(
|
|
94
|
+
"No repository-level base branch configured. Use 'agency base set --repo <branch>' to set one.",
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
// Get current branch
|
|
100
|
+
const currentBranch = yield* git.getCurrentBranch(gitRoot)
|
|
101
|
+
verboseLog(`Current branch: ${highlight.branch(currentBranch)}`)
|
|
102
|
+
|
|
103
|
+
// Get branch-specific base branch from agency.json
|
|
104
|
+
verboseLog("Reading branch-specific base branch from agency.json")
|
|
105
|
+
currentBase = yield* Effect.tryPromise({
|
|
106
|
+
try: () => getBaseBranchFromMetadata(gitRoot),
|
|
107
|
+
catch: (error) =>
|
|
108
|
+
new Error(`Failed to get base branch from metadata: ${error}`),
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
if (!currentBase) {
|
|
112
|
+
return yield* Effect.fail(
|
|
113
|
+
new Error(
|
|
114
|
+
`No base branch configured for ${highlight.branch(currentBranch)}. Use 'agency base set <branch>' to set one.`,
|
|
115
|
+
),
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
log(currentBase)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
export const base = (options: BaseOptions) =>
|
|
124
|
+
Effect.gen(function* () {
|
|
125
|
+
const {
|
|
126
|
+
subcommand,
|
|
127
|
+
args,
|
|
128
|
+
repo = false,
|
|
129
|
+
silent = false,
|
|
130
|
+
verbose = false,
|
|
131
|
+
} = options
|
|
132
|
+
|
|
133
|
+
if (!subcommand) {
|
|
134
|
+
return yield* Effect.fail(
|
|
135
|
+
new Error("Subcommand is required. Usage: agency base <subcommand>"),
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
switch (subcommand) {
|
|
140
|
+
case "set": {
|
|
141
|
+
if (!args[0]) {
|
|
142
|
+
return yield* Effect.fail(
|
|
143
|
+
new Error(
|
|
144
|
+
"Base branch argument is required. Usage: agency base set <branch>",
|
|
145
|
+
),
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
return yield* baseSetEffect({
|
|
149
|
+
baseBranch: args[0],
|
|
150
|
+
repo,
|
|
151
|
+
silent,
|
|
152
|
+
verbose,
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
case "get": {
|
|
156
|
+
return yield* baseGetEffect({
|
|
157
|
+
repo,
|
|
158
|
+
silent,
|
|
159
|
+
verbose,
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
return yield* Effect.fail(
|
|
164
|
+
new Error(
|
|
165
|
+
`Unknown subcommand '${subcommand}'. Available subcommands: set, get`,
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
export const help = `
|
|
172
|
+
Usage: agency base <subcommand> [options]
|
|
173
|
+
|
|
174
|
+
Get or set the base branch for the current feature branch.
|
|
175
|
+
|
|
176
|
+
Subcommands:
|
|
177
|
+
set <branch> Set the base branch for the current feature branch
|
|
178
|
+
get Get the configured base branch
|
|
179
|
+
|
|
180
|
+
Options:
|
|
181
|
+
--repo Use repository-level default instead of branch-specific
|
|
182
|
+
-h, --help Show this help message
|
|
183
|
+
-s, --silent Suppress output messages
|
|
184
|
+
-v, --verbose Show verbose output
|
|
185
|
+
|
|
186
|
+
Examples:
|
|
187
|
+
agency base set origin/main # Set base branch for current branch
|
|
188
|
+
agency base set --repo origin/main # Set repository-level default for all branches
|
|
189
|
+
agency base get # Get branch-specific base branch
|
|
190
|
+
agency base get --repo # Get repository-level default base branch
|
|
191
|
+
|
|
192
|
+
Notes:
|
|
193
|
+
- The base branch must exist in the repository
|
|
194
|
+
- Branch-specific base branch is saved in agency.json (committed with the branch)
|
|
195
|
+
- Repository-level default is saved in .git/config (not committed)
|
|
196
|
+
- Branch-specific settings take precedence over repository-level defaults
|
|
197
|
+
- Base branch configuration is used by 'agency emit' when creating emit branches
|
|
198
|
+
`
|