chief-clancy 0.2.0-beta.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -24
- package/dist/installer/file-ops/file-ops.d.ts +32 -0
- package/dist/installer/file-ops/file-ops.d.ts.map +1 -0
- package/dist/installer/file-ops/file-ops.js +58 -0
- package/dist/installer/file-ops/file-ops.js.map +1 -0
- package/dist/installer/hook-installer/hook-installer.d.ts +29 -0
- package/dist/installer/hook-installer/hook-installer.d.ts.map +1 -0
- package/dist/installer/hook-installer/hook-installer.js +96 -0
- package/dist/installer/hook-installer/hook-installer.js.map +1 -0
- package/dist/installer/install.d.ts +3 -0
- package/dist/installer/install.d.ts.map +1 -0
- package/dist/installer/install.js +227 -0
- package/dist/installer/install.js.map +1 -0
- package/dist/installer/manifest/manifest.d.ts +41 -0
- package/dist/installer/manifest/manifest.d.ts.map +1 -0
- package/dist/installer/manifest/manifest.js +97 -0
- package/dist/installer/manifest/manifest.js.map +1 -0
- package/dist/installer/prompts/prompts.d.ts +33 -0
- package/dist/installer/prompts/prompts.d.ts.map +1 -0
- package/dist/installer/prompts/prompts.js +55 -0
- package/dist/installer/prompts/prompts.js.map +1 -0
- package/dist/schemas/env.d.ts +75 -0
- package/dist/schemas/env.d.ts.map +1 -0
- package/dist/schemas/env.js +40 -0
- package/dist/schemas/env.js.map +1 -0
- package/dist/schemas/github.d.ts +27 -0
- package/dist/schemas/github.d.ts.map +1 -0
- package/dist/schemas/github.js +17 -0
- package/dist/schemas/github.js.map +1 -0
- package/dist/schemas/index.d.ts +9 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +5 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/jira.d.ts +37 -0
- package/dist/schemas/jira.d.ts.map +1 -0
- package/dist/schemas/jira.js +37 -0
- package/dist/schemas/jira.js.map +1 -0
- package/dist/schemas/linear.d.ts +67 -0
- package/dist/schemas/linear.d.ts.map +1 -0
- package/dist/schemas/linear.js +50 -0
- package/dist/schemas/linear.js.map +1 -0
- package/dist/scripts/afk/afk.d.ts +21 -0
- package/dist/scripts/afk/afk.d.ts.map +1 -0
- package/dist/scripts/afk/afk.js +116 -0
- package/dist/scripts/afk/afk.js.map +1 -0
- package/dist/scripts/board/github/github.d.ts +56 -0
- package/dist/scripts/board/github/github.d.ts.map +1 -0
- package/dist/scripts/board/github/github.js +142 -0
- package/dist/scripts/board/github/github.js.map +1 -0
- package/dist/scripts/board/jira/jira.d.ts +90 -0
- package/dist/scripts/board/jira/jira.d.ts.map +1 -0
- package/dist/scripts/board/jira/jira.js +251 -0
- package/dist/scripts/board/jira/jira.js.map +1 -0
- package/dist/scripts/board/linear/linear.d.ts +85 -0
- package/dist/scripts/board/linear/linear.d.ts.map +1 -0
- package/dist/scripts/board/linear/linear.js +209 -0
- package/dist/scripts/board/linear/linear.js.map +1 -0
- package/dist/scripts/once/once.d.ts +12 -0
- package/dist/scripts/once/once.d.ts.map +1 -0
- package/dist/scripts/once/once.js +323 -0
- package/dist/scripts/once/once.js.map +1 -0
- package/dist/scripts/shared/branch/branch.d.ts +50 -0
- package/dist/scripts/shared/branch/branch.d.ts.map +1 -0
- package/dist/scripts/shared/branch/branch.js +61 -0
- package/dist/scripts/shared/branch/branch.js.map +1 -0
- package/dist/scripts/shared/claude-cli/claude-cli.d.ts +17 -0
- package/dist/scripts/shared/claude-cli/claude-cli.d.ts.map +1 -0
- package/dist/scripts/shared/claude-cli/claude-cli.js +35 -0
- package/dist/scripts/shared/claude-cli/claude-cli.js.map +1 -0
- package/dist/scripts/shared/env-parser/env-parser.d.ts +30 -0
- package/dist/scripts/shared/env-parser/env-parser.d.ts.map +1 -0
- package/dist/scripts/shared/env-parser/env-parser.js +64 -0
- package/dist/scripts/shared/env-parser/env-parser.js.map +1 -0
- package/dist/scripts/shared/env-schema/env-schema.d.ts +27 -0
- package/dist/scripts/shared/env-schema/env-schema.d.ts.map +1 -0
- package/dist/scripts/shared/env-schema/env-schema.js +46 -0
- package/dist/scripts/shared/env-schema/env-schema.js.map +1 -0
- package/dist/scripts/shared/git-ops/git-ops.d.ts +52 -0
- package/dist/scripts/shared/git-ops/git-ops.d.ts.map +1 -0
- package/dist/scripts/shared/git-ops/git-ops.js +107 -0
- package/dist/scripts/shared/git-ops/git-ops.js.map +1 -0
- package/dist/scripts/shared/http/http.d.ts +52 -0
- package/dist/scripts/shared/http/http.d.ts.map +1 -0
- package/dist/scripts/shared/http/http.js +74 -0
- package/dist/scripts/shared/http/http.js.map +1 -0
- package/dist/scripts/shared/notify/notify.d.ts +46 -0
- package/dist/scripts/shared/notify/notify.d.ts.map +1 -0
- package/dist/scripts/shared/notify/notify.js +88 -0
- package/dist/scripts/shared/notify/notify.js.map +1 -0
- package/dist/scripts/shared/preflight/preflight.d.ts +40 -0
- package/dist/scripts/shared/preflight/preflight.d.ts.map +1 -0
- package/dist/scripts/shared/preflight/preflight.js +84 -0
- package/dist/scripts/shared/preflight/preflight.js.map +1 -0
- package/dist/scripts/shared/progress/progress.d.ts +25 -0
- package/dist/scripts/shared/progress/progress.d.ts.map +1 -0
- package/dist/scripts/shared/progress/progress.js +46 -0
- package/dist/scripts/shared/progress/progress.js.map +1 -0
- package/dist/scripts/shared/prompt/prompt.d.ts +38 -0
- package/dist/scripts/shared/prompt/prompt.d.ts.map +1 -0
- package/dist/scripts/shared/prompt/prompt.js +77 -0
- package/dist/scripts/shared/prompt/prompt.js.map +1 -0
- package/dist/types/board.d.ts +13 -0
- package/dist/types/board.d.ts.map +1 -0
- package/dist/types/board.js +5 -0
- package/dist/types/board.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/ansi/ansi.d.ts +55 -0
- package/dist/utils/ansi/ansi.d.ts.map +1 -0
- package/dist/utils/ansi/ansi.js +55 -0
- package/dist/utils/ansi/ansi.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/parse-json/parse-json.d.ts +20 -0
- package/dist/utils/parse-json/parse-json.d.ts.map +1 -0
- package/dist/utils/parse-json/parse-json.js +27 -0
- package/dist/utils/parse-json/parse-json.js.map +1 -0
- package/hooks/clancy-check-update.js +2 -2
- package/hooks/clancy-credential-guard.js +8 -1
- package/package.json +52 -8
- package/registry/boards.json +3 -6
- package/src/templates/CLAUDE.md +1 -1
- package/src/workflows/doctor.md +32 -23
- package/src/workflows/init.md +88 -19
- package/src/workflows/logs.md +13 -6
- package/src/workflows/map-codebase.md +17 -16
- package/src/workflows/once.md +22 -12
- package/src/workflows/review.md +40 -27
- package/src/workflows/run.md +20 -12
- package/src/workflows/scaffold.md +12 -1023
- package/src/workflows/settings.md +9 -6
- package/src/workflows/status.md +17 -8
- package/src/workflows/uninstall.md +11 -6
- package/src/workflows/update.md +13 -11
- package/bin/install.js +0 -362
- package/src/templates/scripts/clancy-afk.sh +0 -111
- package/src/templates/scripts/clancy-once-github.sh +0 -249
- package/src/templates/scripts/clancy-once-linear.sh +0 -320
- package/src/templates/scripts/clancy-once.sh +0 -322
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board detection from raw `.clancy/.env` variables.
|
|
3
|
+
*
|
|
4
|
+
* Validates env vars against Zod schemas and returns a typed
|
|
5
|
+
* discriminated union for the detected board provider.
|
|
6
|
+
*/
|
|
7
|
+
import type { BoardConfig } from '../../../schemas/env.js';
|
|
8
|
+
export type { BoardConfig, GitHubEnv, JiraEnv, LinearEnv, SharedEnv, } from '../../../schemas/env.js';
|
|
9
|
+
/**
|
|
10
|
+
* Detect which board is configured from raw env vars and return a typed config.
|
|
11
|
+
*
|
|
12
|
+
* Detection priority: Jira → GitHub → Linear (checked by presence of
|
|
13
|
+
* board-specific required keys). Returns the first match.
|
|
14
|
+
*
|
|
15
|
+
* @param raw - The raw key-value record from `.clancy/.env`.
|
|
16
|
+
* @returns A typed `BoardConfig` or an error string if no board is detected
|
|
17
|
+
* or validation fails.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const result = detectBoard({ GITHUB_TOKEN: 'ghp_xxx', GITHUB_REPO: 'acme/app' });
|
|
22
|
+
* if (typeof result === 'string') console.error(result);
|
|
23
|
+
* else console.log(result.provider); // 'github'
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectBoard(raw: Record<string, string>): BoardConfig | string;
|
|
27
|
+
//# sourceMappingURL=env-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-schema.d.ts","sourceRoot":"","sources":["../../../../src/scripts/shared/env-schema/env-schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQpD,YAAY,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,SAAS,GACV,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,GAAG,MAAM,CAmC7E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { githubEnvSchema, jiraEnvSchema, linearEnvSchema, } from '../../../schemas/env.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect which board is configured from raw env vars and return a typed config.
|
|
4
|
+
*
|
|
5
|
+
* Detection priority: Jira → GitHub → Linear (checked by presence of
|
|
6
|
+
* board-specific required keys). Returns the first match.
|
|
7
|
+
*
|
|
8
|
+
* @param raw - The raw key-value record from `.clancy/.env`.
|
|
9
|
+
* @returns A typed `BoardConfig` or an error string if no board is detected
|
|
10
|
+
* or validation fails.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const result = detectBoard({ GITHUB_TOKEN: 'ghp_xxx', GITHUB_REPO: 'acme/app' });
|
|
15
|
+
* if (typeof result === 'string') console.error(result);
|
|
16
|
+
* else console.log(result.provider); // 'github'
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function detectBoard(raw) {
|
|
20
|
+
// Jira — check for JIRA_BASE_URL as the distinguishing key
|
|
21
|
+
if (raw.JIRA_BASE_URL) {
|
|
22
|
+
const parsed = jiraEnvSchema.safeParse(raw);
|
|
23
|
+
if (!parsed.success) {
|
|
24
|
+
return `✗ Jira env validation failed: ${parsed.error.message}`;
|
|
25
|
+
}
|
|
26
|
+
return { provider: 'jira', env: parsed.data };
|
|
27
|
+
}
|
|
28
|
+
// GitHub — check for GITHUB_TOKEN as the distinguishing key
|
|
29
|
+
if (raw.GITHUB_TOKEN) {
|
|
30
|
+
const parsed = githubEnvSchema.safeParse(raw);
|
|
31
|
+
if (!parsed.success) {
|
|
32
|
+
return `✗ GitHub env validation failed: ${parsed.error.message}`;
|
|
33
|
+
}
|
|
34
|
+
return { provider: 'github', env: parsed.data };
|
|
35
|
+
}
|
|
36
|
+
// Linear — check for LINEAR_API_KEY as the distinguishing key
|
|
37
|
+
if (raw.LINEAR_API_KEY) {
|
|
38
|
+
const parsed = linearEnvSchema.safeParse(raw);
|
|
39
|
+
if (!parsed.success) {
|
|
40
|
+
return `✗ Linear env validation failed: ${parsed.error.message}`;
|
|
41
|
+
}
|
|
42
|
+
return { provider: 'linear', env: parsed.data };
|
|
43
|
+
}
|
|
44
|
+
return '✗ No board detected — set Jira, GitHub, or Linear credentials in .clancy/.env';
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=env-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-schema.js","sourceRoot":"","sources":["../../../../src/scripts/shared/env-schema/env-schema.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,eAAe,EACf,aAAa,EACb,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAW1B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAC,GAA2B;IACrD,2DAA2D;IAC3D,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,iCAAiC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACjE,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;IAED,4DAA4D;IAC5D,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnE,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,8DAA8D;IAC9D,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnE,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,+EAA+E,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the name of the currently checked-out branch.
|
|
3
|
+
*
|
|
4
|
+
* @returns The current branch name.
|
|
5
|
+
*/
|
|
6
|
+
export declare function currentBranch(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Check whether the working directory has uncommitted changes.
|
|
9
|
+
*
|
|
10
|
+
* @returns `true` if there are staged or unstaged changes.
|
|
11
|
+
*/
|
|
12
|
+
export declare function hasUncommittedChanges(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a local branch exists.
|
|
15
|
+
*
|
|
16
|
+
* @param branch - The branch name to check.
|
|
17
|
+
* @returns `true` if the branch exists locally.
|
|
18
|
+
*/
|
|
19
|
+
export declare function branchExists(branch: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Create a branch from a base branch if it doesn't already exist.
|
|
22
|
+
*
|
|
23
|
+
* @param branch - The branch name to create.
|
|
24
|
+
* @param baseBranch - The base branch to create from.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureBranch(branch: string, baseBranch: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Check out a branch. Uses `-B` flag to force-create if needed.
|
|
29
|
+
*
|
|
30
|
+
* @param branch - The branch name to check out.
|
|
31
|
+
* @param force - If `true`, uses `-B` to force-create/reset the branch.
|
|
32
|
+
*/
|
|
33
|
+
export declare function checkout(branch: string, force?: boolean): void;
|
|
34
|
+
/**
|
|
35
|
+
* Squash merge a source branch into the currently checked-out branch
|
|
36
|
+
* and commit with the given message.
|
|
37
|
+
*
|
|
38
|
+
* @param sourceBranch - The branch to squash merge from.
|
|
39
|
+
* @param commitMessage - The commit message for the squash merge.
|
|
40
|
+
* @returns `true` if changes were committed, `false` if there was nothing to commit.
|
|
41
|
+
*/
|
|
42
|
+
export declare function squashMerge(sourceBranch: string, commitMessage: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Delete a local branch (force).
|
|
45
|
+
*
|
|
46
|
+
* Uses `-D` because squash merges leave the branch in an "unmerged" state
|
|
47
|
+
* from git's perspective, causing `-d` to fail.
|
|
48
|
+
*
|
|
49
|
+
* @param branch - The branch name to delete.
|
|
50
|
+
*/
|
|
51
|
+
export declare function deleteBranch(branch: string): void;
|
|
52
|
+
//# sourceMappingURL=git-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-ops.d.ts","sourceRoot":"","sources":["../../../../src/scripts/shared/git-ops/git-ops.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAQ/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAapD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAIrE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,IAAI,CAE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAUT;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEjD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git operations shared across board scripts.
|
|
3
|
+
*
|
|
4
|
+
* Wraps common git commands used during the ticket lifecycle:
|
|
5
|
+
* branch creation, checkout, squash merge, and cleanup.
|
|
6
|
+
*/
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
/**
|
|
9
|
+
* Run a git command and return trimmed stdout.
|
|
10
|
+
*
|
|
11
|
+
* @param args - The git sub-command and its arguments.
|
|
12
|
+
* @returns The trimmed stdout output.
|
|
13
|
+
*/
|
|
14
|
+
function git(...args) {
|
|
15
|
+
return execFileSync('git', args, { encoding: 'utf8' }).trim();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the name of the currently checked-out branch.
|
|
19
|
+
*
|
|
20
|
+
* @returns The current branch name.
|
|
21
|
+
*/
|
|
22
|
+
export function currentBranch() {
|
|
23
|
+
return git('rev-parse', '--abbrev-ref', 'HEAD');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check whether the working directory has uncommitted changes.
|
|
27
|
+
*
|
|
28
|
+
* @returns `true` if there are staged or unstaged changes.
|
|
29
|
+
*/
|
|
30
|
+
export function hasUncommittedChanges() {
|
|
31
|
+
try {
|
|
32
|
+
execFileSync('git', ['diff', '--quiet'], { stdio: 'ignore' });
|
|
33
|
+
execFileSync('git', ['diff', '--cached', '--quiet'], { stdio: 'ignore' });
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check whether a local branch exists.
|
|
42
|
+
*
|
|
43
|
+
* @param branch - The branch name to check.
|
|
44
|
+
* @returns `true` if the branch exists locally.
|
|
45
|
+
*/
|
|
46
|
+
export function branchExists(branch) {
|
|
47
|
+
try {
|
|
48
|
+
execFileSync('git', ['show-ref', '--verify', '--quiet', `refs/heads/${branch}`], {
|
|
49
|
+
stdio: 'ignore',
|
|
50
|
+
});
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a branch from a base branch if it doesn't already exist.
|
|
59
|
+
*
|
|
60
|
+
* @param branch - The branch name to create.
|
|
61
|
+
* @param baseBranch - The base branch to create from.
|
|
62
|
+
*/
|
|
63
|
+
export function ensureBranch(branch, baseBranch) {
|
|
64
|
+
if (!branchExists(branch)) {
|
|
65
|
+
git('checkout', '-b', branch, baseBranch);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check out a branch. Uses `-B` flag to force-create if needed.
|
|
70
|
+
*
|
|
71
|
+
* @param branch - The branch name to check out.
|
|
72
|
+
* @param force - If `true`, uses `-B` to force-create/reset the branch.
|
|
73
|
+
*/
|
|
74
|
+
export function checkout(branch, force = false) {
|
|
75
|
+
git('checkout', ...(force ? ['-B'] : []), branch);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Squash merge a source branch into the currently checked-out branch
|
|
79
|
+
* and commit with the given message.
|
|
80
|
+
*
|
|
81
|
+
* @param sourceBranch - The branch to squash merge from.
|
|
82
|
+
* @param commitMessage - The commit message for the squash merge.
|
|
83
|
+
* @returns `true` if changes were committed, `false` if there was nothing to commit.
|
|
84
|
+
*/
|
|
85
|
+
export function squashMerge(sourceBranch, commitMessage) {
|
|
86
|
+
git('merge', '--squash', sourceBranch);
|
|
87
|
+
try {
|
|
88
|
+
execFileSync('git', ['diff', '--cached', '--quiet'], { stdio: 'ignore' });
|
|
89
|
+
return false; // nothing staged
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
execFileSync('git', ['commit', '-m', commitMessage], { encoding: 'utf8' });
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Delete a local branch (force).
|
|
98
|
+
*
|
|
99
|
+
* Uses `-D` because squash merges leave the branch in an "unmerged" state
|
|
100
|
+
* from git's perspective, causing `-d` to fail.
|
|
101
|
+
*
|
|
102
|
+
* @param branch - The branch name to delete.
|
|
103
|
+
*/
|
|
104
|
+
export function deleteBranch(branch) {
|
|
105
|
+
git('branch', '-D', branch);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=git-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-ops.js","sourceRoot":"","sources":["../../../../src/scripts/shared/git-ops/git-ops.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;GAKG;AACH,SAAS,GAAG,CAAC,GAAG,IAAc;IAC5B,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9D,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,IAAI,CAAC;QACH,YAAY,CACV,KAAK,EACL,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,MAAM,EAAE,CAAC,EAC3D;YACE,KAAK,EAAE,QAAQ;SAChB,CACF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,UAAkB;IAC7D,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,KAAK,GAAG,KAAK;IACpD,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,YAAoB,EACpB,aAAqB;IAErB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC,CAAC,iBAAiB;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP helpers for board scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provides a generic ping function and header builders to reduce
|
|
5
|
+
* boilerplate across Jira, GitHub, and Linear integrations.
|
|
6
|
+
*/
|
|
7
|
+
/** Standard error messages mapped to HTTP status codes. */
|
|
8
|
+
type StatusErrorMap = Record<number, string>;
|
|
9
|
+
/** Result from a ping or connectivity check. */
|
|
10
|
+
export type PingResult = {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Ping an API endpoint and map common HTTP error codes to messages.
|
|
16
|
+
*
|
|
17
|
+
* Returns `{ ok: true }` on success, or `{ ok: false, error }` with
|
|
18
|
+
* a human-readable message on failure.
|
|
19
|
+
*
|
|
20
|
+
* @param url - The URL to ping.
|
|
21
|
+
* @param headers - HTTP headers to send.
|
|
22
|
+
* @param statusErrors - Map of HTTP status codes to error messages.
|
|
23
|
+
* @param networkError - Error message for network failures.
|
|
24
|
+
* @returns A ping result with `ok` and optional `error`.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const result = await pingEndpoint(
|
|
29
|
+
* 'https://api.github.com/repos/owner/repo',
|
|
30
|
+
* { Authorization: 'Bearer tok_xxx' },
|
|
31
|
+
* { 401: '✗ Auth failed', 404: '✗ Not found' },
|
|
32
|
+
* '✗ Could not reach GitHub',
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function pingEndpoint(url: string, headers: Record<string, string>, statusErrors: StatusErrorMap, networkError: string): Promise<PingResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Build standard GitHub API request headers.
|
|
39
|
+
*
|
|
40
|
+
* @param token - The GitHub personal access token.
|
|
41
|
+
* @returns Headers object for GitHub REST API requests.
|
|
42
|
+
*/
|
|
43
|
+
export declare function githubHeaders(token: string): Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Build standard Jira API request headers.
|
|
46
|
+
*
|
|
47
|
+
* @param auth - The Base64-encoded Basic auth string.
|
|
48
|
+
* @returns Headers object for Jira REST API requests.
|
|
49
|
+
*/
|
|
50
|
+
export declare function jiraHeaders(auth: string): Record<string, string>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/scripts/shared/http/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,2DAA2D;AAC3D,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7C,gDAAgD;AAChD,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,YAAY,EAAE,cAAc,EAC5B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKhE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP helpers for board scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provides a generic ping function and header builders to reduce
|
|
5
|
+
* boilerplate across Jira, GitHub, and Linear integrations.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Ping an API endpoint and map common HTTP error codes to messages.
|
|
9
|
+
*
|
|
10
|
+
* Returns `{ ok: true }` on success, or `{ ok: false, error }` with
|
|
11
|
+
* a human-readable message on failure.
|
|
12
|
+
*
|
|
13
|
+
* @param url - The URL to ping.
|
|
14
|
+
* @param headers - HTTP headers to send.
|
|
15
|
+
* @param statusErrors - Map of HTTP status codes to error messages.
|
|
16
|
+
* @param networkError - Error message for network failures.
|
|
17
|
+
* @returns A ping result with `ok` and optional `error`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const result = await pingEndpoint(
|
|
22
|
+
* 'https://api.github.com/repos/owner/repo',
|
|
23
|
+
* { Authorization: 'Bearer tok_xxx' },
|
|
24
|
+
* { 401: '✗ Auth failed', 404: '✗ Not found' },
|
|
25
|
+
* '✗ Could not reach GitHub',
|
|
26
|
+
* );
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export async function pingEndpoint(url, headers, statusErrors, networkError) {
|
|
30
|
+
try {
|
|
31
|
+
const controller = new AbortController();
|
|
32
|
+
const timeout = setTimeout(() => controller.abort(), 10_000);
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
headers,
|
|
35
|
+
signal: controller.signal,
|
|
36
|
+
});
|
|
37
|
+
clearTimeout(timeout);
|
|
38
|
+
if (response.ok)
|
|
39
|
+
return { ok: true };
|
|
40
|
+
const mapped = statusErrors[response.status];
|
|
41
|
+
if (mapped)
|
|
42
|
+
return { ok: false, error: mapped };
|
|
43
|
+
return { ok: false, error: `✗ HTTP ${response.status}` };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return { ok: false, error: networkError };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build standard GitHub API request headers.
|
|
51
|
+
*
|
|
52
|
+
* @param token - The GitHub personal access token.
|
|
53
|
+
* @returns Headers object for GitHub REST API requests.
|
|
54
|
+
*/
|
|
55
|
+
export function githubHeaders(token) {
|
|
56
|
+
return {
|
|
57
|
+
Authorization: `Bearer ${token}`,
|
|
58
|
+
Accept: 'application/vnd.github+json',
|
|
59
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build standard Jira API request headers.
|
|
64
|
+
*
|
|
65
|
+
* @param auth - The Base64-encoded Basic auth string.
|
|
66
|
+
* @returns Headers object for Jira REST API requests.
|
|
67
|
+
*/
|
|
68
|
+
export function jiraHeaders(auth) {
|
|
69
|
+
return {
|
|
70
|
+
Authorization: `Basic ${auth}`,
|
|
71
|
+
Accept: 'application/json',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../../src/scripts/shared/http/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,OAA+B,EAC/B,YAA4B,EAC5B,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QAE7D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO;YACP,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtB,IAAI,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAErC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,MAAM;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAEhD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO;QACL,aAAa,EAAE,UAAU,KAAK,EAAE;QAChC,MAAM,EAAE,6BAA6B;QACrC,sBAAsB,EAAE,YAAY;KACrC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO;QACL,aAAa,EAAE,SAAS,IAAI,EAAE;QAC9B,MAAM,EAAE,kBAAkB;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook notification sender for Slack and Microsoft Teams.
|
|
3
|
+
*
|
|
4
|
+
* Sends completion notifications after a ticket is processed.
|
|
5
|
+
* Best-effort — never throws on failure.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Detect whether a webhook URL is for Slack (vs Teams/other).
|
|
9
|
+
*
|
|
10
|
+
* @param url - The webhook URL to check.
|
|
11
|
+
* @returns `true` if the URL contains `hooks.slack.com`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isSlackWebhook(url: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Build a Slack webhook payload.
|
|
16
|
+
*
|
|
17
|
+
* @param message - The notification message text.
|
|
18
|
+
* @returns The JSON payload string for a Slack incoming webhook.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildSlackPayload(message: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Build a Microsoft Teams webhook payload using an adaptive card.
|
|
23
|
+
*
|
|
24
|
+
* @param message - The notification message text.
|
|
25
|
+
* @returns The JSON payload string for a Teams incoming webhook.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildTeamsPayload(message: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Send a notification to a webhook URL.
|
|
30
|
+
*
|
|
31
|
+
* Automatically detects Slack vs Teams format based on the URL.
|
|
32
|
+
* Best-effort — logs a warning on failure but never throws.
|
|
33
|
+
*
|
|
34
|
+
* @param webhookUrl - The Slack or Teams webhook URL.
|
|
35
|
+
* @param message - The notification message to send.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* await sendNotification(
|
|
40
|
+
* 'https://hooks.slack.com/services/xxx/yyy/zzz',
|
|
41
|
+
* '✓ Clancy completed [PROJ-123] Add login page',
|
|
42
|
+
* );
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function sendNotification(webhookUrl: string, message: string): Promise<void>;
|
|
46
|
+
//# sourceMappingURL=notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../src/scripts/shared/notify/notify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAqBzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook notification sender for Slack and Microsoft Teams.
|
|
3
|
+
*
|
|
4
|
+
* Sends completion notifications after a ticket is processed.
|
|
5
|
+
* Best-effort — never throws on failure.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Detect whether a webhook URL is for Slack (vs Teams/other).
|
|
9
|
+
*
|
|
10
|
+
* @param url - The webhook URL to check.
|
|
11
|
+
* @returns `true` if the URL contains `hooks.slack.com`.
|
|
12
|
+
*/
|
|
13
|
+
export function isSlackWebhook(url) {
|
|
14
|
+
return url.includes('hooks.slack.com');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build a Slack webhook payload.
|
|
18
|
+
*
|
|
19
|
+
* @param message - The notification message text.
|
|
20
|
+
* @returns The JSON payload string for a Slack incoming webhook.
|
|
21
|
+
*/
|
|
22
|
+
export function buildSlackPayload(message) {
|
|
23
|
+
return JSON.stringify({ text: message });
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build a Microsoft Teams webhook payload using an adaptive card.
|
|
27
|
+
*
|
|
28
|
+
* @param message - The notification message text.
|
|
29
|
+
* @returns The JSON payload string for a Teams incoming webhook.
|
|
30
|
+
*/
|
|
31
|
+
export function buildTeamsPayload(message) {
|
|
32
|
+
return JSON.stringify({
|
|
33
|
+
type: 'message',
|
|
34
|
+
attachments: [
|
|
35
|
+
{
|
|
36
|
+
contentType: 'application/vnd.microsoft.card.adaptive',
|
|
37
|
+
content: {
|
|
38
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
39
|
+
type: 'AdaptiveCard',
|
|
40
|
+
version: '1.4',
|
|
41
|
+
body: [
|
|
42
|
+
{
|
|
43
|
+
type: 'TextBlock',
|
|
44
|
+
text: message,
|
|
45
|
+
wrap: true,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Send a notification to a webhook URL.
|
|
55
|
+
*
|
|
56
|
+
* Automatically detects Slack vs Teams format based on the URL.
|
|
57
|
+
* Best-effort — logs a warning on failure but never throws.
|
|
58
|
+
*
|
|
59
|
+
* @param webhookUrl - The Slack or Teams webhook URL.
|
|
60
|
+
* @param message - The notification message to send.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* await sendNotification(
|
|
65
|
+
* 'https://hooks.slack.com/services/xxx/yyy/zzz',
|
|
66
|
+
* '✓ Clancy completed [PROJ-123] Add login page',
|
|
67
|
+
* );
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export async function sendNotification(webhookUrl, message) {
|
|
71
|
+
const payload = isSlackWebhook(webhookUrl)
|
|
72
|
+
? buildSlackPayload(message)
|
|
73
|
+
: buildTeamsPayload(message);
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(webhookUrl, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
headers: { 'Content-Type': 'application/json' },
|
|
78
|
+
body: payload,
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
console.warn(`⚠ Notification failed: HTTP ${response.status}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
console.warn('⚠ Notification failed: could not reach webhook');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../src/scripts/shared/notify/notify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE;YACX;gBACE,WAAW,EAAE,yCAAyC;gBACtD,OAAO,EAAE;oBACP,OAAO,EAAE,oDAAoD;oBAC7D,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE;wBACJ;4BACE,IAAI,EAAE,WAAW;4BACjB,IAAI,EAAE,OAAO;4BACb,IAAI,EAAE,IAAI;yBACX;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,UAAkB,EAClB,OAAe;IAEf,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC;QACxC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC;QAC5B,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACvC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,+BAA+B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
type PreflightResult = {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
warning?: string;
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Check whether a binary is available on the system PATH.
|
|
9
|
+
*
|
|
10
|
+
* @param name - The binary name to check (e.g., `'git'`, `'curl'`).
|
|
11
|
+
* @returns `true` if the binary is found.
|
|
12
|
+
*/
|
|
13
|
+
export declare function binaryExists(name: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check whether the current directory is inside a git repository.
|
|
16
|
+
*
|
|
17
|
+
* @returns `true` if a `.git` directory is found.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isGitRepo(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Run all preflight checks common to every board script.
|
|
22
|
+
*
|
|
23
|
+
* Checks for required binaries (`claude`, `git`), the `.clancy/.env` file,
|
|
24
|
+
* git repository state, and uncommitted changes.
|
|
25
|
+
*
|
|
26
|
+
* @param projectRoot - The root directory of the project.
|
|
27
|
+
* @returns A result object with `ok`, optional `error`/`warning`, and parsed `env`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const result = runPreflight('/path/to/project');
|
|
32
|
+
* if (!result.ok) {
|
|
33
|
+
* console.error(result.error);
|
|
34
|
+
* process.exit(0);
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function runPreflight(projectRoot: string): PreflightResult;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../../../src/scripts/shared/preflight/preflight.ts"],"names":[],"mappings":"AAWA,KAAK,eAAe,GAAG;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAOnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAgCjE"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight checks shared across board scripts.
|
|
3
|
+
*
|
|
4
|
+
* Validates the environment before running a ticket:
|
|
5
|
+
* required binaries, .env file, git repository, and working directory state.
|
|
6
|
+
*/
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
import { loadClancyEnv } from '../../../scripts/shared/env-parser/env-parser.js';
|
|
9
|
+
import { hasUncommittedChanges } from '../../../scripts/shared/git-ops/git-ops.js';
|
|
10
|
+
/**
|
|
11
|
+
* Check whether a binary is available on the system PATH.
|
|
12
|
+
*
|
|
13
|
+
* @param name - The binary name to check (e.g., `'git'`, `'curl'`).
|
|
14
|
+
* @returns `true` if the binary is found.
|
|
15
|
+
*/
|
|
16
|
+
export function binaryExists(name) {
|
|
17
|
+
try {
|
|
18
|
+
execFileSync('which', [name], { stdio: 'ignore' });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check whether the current directory is inside a git repository.
|
|
27
|
+
*
|
|
28
|
+
* @returns `true` if a `.git` directory is found.
|
|
29
|
+
*/
|
|
30
|
+
export function isGitRepo() {
|
|
31
|
+
try {
|
|
32
|
+
execFileSync('git', ['rev-parse', '--git-dir'], { stdio: 'ignore' });
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run all preflight checks common to every board script.
|
|
41
|
+
*
|
|
42
|
+
* Checks for required binaries (`claude`, `git`), the `.clancy/.env` file,
|
|
43
|
+
* git repository state, and uncommitted changes.
|
|
44
|
+
*
|
|
45
|
+
* @param projectRoot - The root directory of the project.
|
|
46
|
+
* @returns A result object with `ok`, optional `error`/`warning`, and parsed `env`.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const result = runPreflight('/path/to/project');
|
|
51
|
+
* if (!result.ok) {
|
|
52
|
+
* console.error(result.error);
|
|
53
|
+
* process.exit(0);
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function runPreflight(projectRoot) {
|
|
58
|
+
// Check required binaries
|
|
59
|
+
for (const bin of ['claude', 'git']) {
|
|
60
|
+
if (!binaryExists(bin)) {
|
|
61
|
+
return { ok: false, error: `✗ ${bin} is required but not found` };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Check .env file
|
|
65
|
+
const env = loadClancyEnv(projectRoot);
|
|
66
|
+
if (!env) {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
error: '✗ .clancy/.env not found — run /clancy:init first',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Check git repo
|
|
73
|
+
if (!isGitRepo()) {
|
|
74
|
+
return { ok: false, error: '✗ Not inside a git repository' };
|
|
75
|
+
}
|
|
76
|
+
// Warn about uncommitted changes
|
|
77
|
+
let warning;
|
|
78
|
+
if (hasUncommittedChanges()) {
|
|
79
|
+
warning =
|
|
80
|
+
'⚠ Working directory has uncommitted changes — they will be included in the branch';
|
|
81
|
+
}
|
|
82
|
+
return { ok: true, env, warning };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../../src/scripts/shared/preflight/preflight.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAS5E;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,0BAA0B;IAC1B,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,4BAA4B,EAAE,CAAC;QACpE,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,mDAAmD;SAC3D,CAAC;IACJ,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;IAC/D,CAAC;IAED,iCAAiC;IACjC,IAAI,OAA2B,CAAC;IAEhC,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAC5B,OAAO;YACL,mFAAmF,CAAC;IACxF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}
|