@coralai/sps-cli 0.6.0 → 0.7.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 ADDED
@@ -0,0 +1,91 @@
1
+ # @coralai/sps-cli
2
+
3
+ AI-driven development pipeline orchestrator. Automates the full development lifecycle from task creation to code merge and deployment.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @coralai/sps-cli
9
+ ```
10
+
11
+ Requires Node.js >= 18.
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ sps <command> [subcommand] <project> [options]
17
+ ```
18
+
19
+ ### Commands
20
+
21
+ | Command | Description | Usage |
22
+ |---------|-------------|-------|
23
+ | `tick` | Run continuous pipeline | `sps tick <project> [--once]` |
24
+ | `card` | Card management | `sps card add <project> "<title>" ["desc"]` |
25
+ | `doctor` | Project health check | `sps doctor <project> [--json] [--skip-remote]` |
26
+ | `scheduler` | Planning → Backlog promotion | `sps scheduler <tick\|inspect\|validate> <project>` |
27
+ | `pipeline` | Execution chain (Backlog → Todo → Inprogress) | `sps pipeline <tick\|inspect> <project>` |
28
+ | `worker` | Worker lifecycle management | `sps worker <launch\|release\|inspect> <project> [seq\|slot]` |
29
+ | `pm` | PM backend operations | `sps pm <scan\|move\|comment\|checklist> <project> [args...]` |
30
+ | `qa` | QA / closeout (QA → merge → Done) | `sps qa <tick\|inspect> <project>` |
31
+ | `monitor` | Anomaly detection and diagnostics | `sps monitor <tick\|inspect-worker\|inspect-card> <project>` |
32
+ | `project` | Project init and validation | `sps project <init\|doctor\|validate\|paths> <project>` |
33
+
34
+ ### Global Options
35
+
36
+ - `--json` — Output structured JSON
37
+ - `--dry-run` — Preview actions without executing
38
+ - `--help` — Show help
39
+ - `--version` — Show version
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ # Initialize a new project
45
+ sps project init my-project
46
+
47
+ # Run health check
48
+ sps doctor my-project
49
+
50
+ # Add a task card
51
+ sps card add my-project "feat: implement user auth" "Add JWT-based authentication"
52
+
53
+ # Run pipeline (single tick)
54
+ sps tick my-project --once
55
+
56
+ # Run pipeline (continuous)
57
+ sps tick my-project
58
+ ```
59
+
60
+ ## Multi-Project Support
61
+
62
+ Run multiple projects in a single process:
63
+
64
+ ```bash
65
+ sps tick project-a project-b project-c
66
+ ```
67
+
68
+ Each project is fully isolated with its own context, providers, engines, lock, and state. One project's error does not affect others.
69
+
70
+ ## Architecture
71
+
72
+ SPS orchestrates a state machine pipeline:
73
+
74
+ ```
75
+ Backlog → Todo → InProgress → QA → Done
76
+ ```
77
+
78
+ ### Supported Backends
79
+
80
+ - **Task Management**: Trello, Plane, Markdown
81
+ - **Repository**: GitLab
82
+ - **Workers**: Claude Code, OpenAI Codex
83
+ - **Notifications**: Matrix
84
+
85
+ ## Configuration
86
+
87
+ Projects are configured via `~/.projects/<name>/conf`. Run `sps project init <name>` to generate a template.
88
+
89
+ ## License
90
+
91
+ MIT
@@ -1 +1 @@
1
- {"version":3,"file":"projectInit.d.ts","sourceRoot":"","sources":["../../src/commands/projectInit.ts"],"names":[],"mappings":"AAOA,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CA6Ef"}
1
+ {"version":3,"file":"projectInit.d.ts","sourceRoot":"","sources":["../../src/commands/projectInit.ts"],"names":[],"mappings":"AAwBA,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CA6Ef"}
@@ -1,8 +1,26 @@
1
1
  import { existsSync, mkdirSync, copyFileSync, writeFileSync, readFileSync, chmodSync } from 'node:fs';
2
- import { resolve } from 'node:path';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
3
4
  import { Logger } from '../core/logger.js';
4
5
  const HOME = process.env.HOME || '/home/coral';
5
- const TEMPLATE_DIR = resolve(HOME, 'jarvis-skills', 'coding-work-flow', 'project-template');
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ // Look for project-template relative to the package root (works for both npm install and source)
8
+ function findTemplateDir() {
9
+ // When installed via npm: dist/commands/projectInit.js → ../../project-template
10
+ const npmPath = resolve(__dirname, '..', '..', 'project-template');
11
+ if (existsSync(npmPath))
12
+ return npmPath;
13
+ // When running from source repo: src/commands/ → ../../../project-template
14
+ const srcPath = resolve(__dirname, '..', '..', '..', 'project-template');
15
+ if (existsSync(srcPath))
16
+ return srcPath;
17
+ // Legacy fallback
18
+ const legacyPath = resolve(HOME, 'jarvis-skills', 'coding-work-flow', 'project-template');
19
+ if (existsSync(legacyPath))
20
+ return legacyPath;
21
+ return npmPath; // default, will fail gracefully below
22
+ }
23
+ const TEMPLATE_DIR = findTemplateDir();
6
24
  export async function executeProjectInit(project, flags) {
7
25
  const log = new Logger('project-init', project);
8
26
  if (!project) {
@@ -1 +1 @@
1
- {"version":3,"file":"projectInit.js","sourceRoot":"","sources":["../../src/commands/projectInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,aAAa,CAAC;AAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;AAE5F,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,KAA8B;IAE9B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAEhD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAExD,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5C,GAAG,CAAC,KAAK,CAAC,qCAAqC,WAAW,EAAE,CAAC,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,6BAA6B;IAC7B,MAAM,IAAI,GAAG;QACX,WAAW;QACX,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC;QAC5B,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC;QAC/B,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC;KAChC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpC,GAAG,CAAC,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAChE,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,YAAY,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACzC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAC/B,GAAG,CAAC,EAAE,CAAC,wDAAwD,CAAC,CAAC;IACnE,CAAC;IAED,iBAAiB;IACjB,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACnC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAChC,CAAC;IAED,2DAA2D;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QAC3D,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACjD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;YAC3D,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAChC,GAAG,CAAC,EAAE,CAAC,uDAAuD,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;IAClF,CAAC;IAED,iDAAiD;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACjC,GAAG,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC;IAC9C,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,WAAW,OAAO,mBAAmB,WAAW,EAAE,CAAC,CAAC;IAC3D,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACxB,GAAG,CAAC,IAAI,CAAC,aAAa,OAAO,6CAA6C,CAAC,CAAC;IAC5E,GAAG,CAAC,IAAI,CAAC,wBAAwB,OAAO,QAAQ,CAAC,CAAC;IAClD,GAAG,CAAC,IAAI,CAAC,0BAA0B,OAAO,6BAA6B,CAAC,CAAC;IACzE,GAAG,CAAC,IAAI,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"projectInit.js","sourceRoot":"","sources":["../../src/commands/projectInit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function executeSetup(flags: Record<string, boolean>): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAwBA,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyHhF"}
@@ -0,0 +1,140 @@
1
+ import { existsSync, mkdirSync, writeFileSync, chmodSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { createInterface } from 'node:readline';
4
+ import { Logger } from '../core/logger.js';
5
+ const HOME = process.env.HOME || '/home/coral';
6
+ const ENV_PATH = resolve(HOME, '.jarvis.env');
7
+ const PROJECTS_DIR = resolve(HOME, '.projects');
8
+ function createPrompt() {
9
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
10
+ return {
11
+ ask: (question, defaultValue) => {
12
+ const suffix = defaultValue ? ` [${defaultValue}]` : '';
13
+ return new Promise((resolve) => {
14
+ rl.question(` ${question}${suffix}: `, (answer) => {
15
+ resolve(answer.trim() || defaultValue || '');
16
+ });
17
+ });
18
+ },
19
+ close: () => rl.close(),
20
+ };
21
+ }
22
+ export async function executeSetup(flags) {
23
+ const log = new Logger('setup', '');
24
+ const prompt = createPrompt();
25
+ console.log('');
26
+ console.log(' ██████╗ ██████╗ ██████╗ █████╗ ██╗ ███████╗██████╗ ███████╗');
27
+ console.log(' ██╔════╝██╔═══██╗██╔══██╗██╔══██╗██║ ██╔════╝██╔══██╗██╔════╝');
28
+ console.log(' ██║ ██║ ██║██████╔╝███████║██║ ███████╗██████╔╝███████╗');
29
+ console.log(' ██║ ██║ ██║██╔══██╗██╔══██║██║ ╚════██║██╔═══╝ ╚════██║');
30
+ console.log(' ╚██████╗╚██████╔╝██║ ██║██║ ██║███████╗ ███████║██║ ███████║');
31
+ console.log(' ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚══════╝╚═╝ ╚══════╝');
32
+ console.log('');
33
+ console.log(' AI-Driven Development Pipeline Orchestrator');
34
+ console.log(' ──────────────────────────────────────────────────────────────────────');
35
+ console.log(' Automate the full dev lifecycle: task cards → AI coding → MR → merge.');
36
+ console.log(' Supports Plane/Trello/Markdown, GitLab, Claude Code/Codex, Matrix.');
37
+ console.log(' https://www.npmjs.com/package/@coralai/sps-cli');
38
+ console.log('');
39
+ // ─── Step 1: ~/.projects directory ─────────────────────────────
40
+ if (!existsSync(PROJECTS_DIR)) {
41
+ mkdirSync(PROJECTS_DIR, { recursive: true });
42
+ log.ok(`Created ${PROJECTS_DIR}`);
43
+ }
44
+ else {
45
+ log.ok(`${PROJECTS_DIR} already exists`);
46
+ }
47
+ // ─── Step 2: ~/.jarvis.env ─────────────────────────────────────
48
+ if (existsSync(ENV_PATH) && !flags.force) {
49
+ log.ok(`${ENV_PATH} already exists (use --force to reconfigure)`);
50
+ }
51
+ else {
52
+ console.log('\n Configure global credentials (~/.jarvis.env)\n');
53
+ console.log(' Press Enter to skip optional fields.\n');
54
+ // GitLab
55
+ console.log(' ── GitLab ──');
56
+ const gitlabUrl = await prompt.ask('GITLAB_URL (e.g. https://git.example.com)');
57
+ const gitlabToken = await prompt.ask('GITLAB_TOKEN');
58
+ const gitlabSshHost = await prompt.ask('GITLAB_SSH_HOST', gitlabUrl ? new URL(gitlabUrl).hostname : '');
59
+ const gitlabSshPort = await prompt.ask('GITLAB_SSH_PORT', '22');
60
+ // PM Backend
61
+ console.log('\n ── PM Backend (Plane) ──');
62
+ const planeUrl = await prompt.ask('PLANE_URL (leave empty if not using Plane)');
63
+ const planeApiKey = planeUrl ? await prompt.ask('PLANE_API_KEY') : '';
64
+ const planeWorkspace = planeUrl ? await prompt.ask('PLANE_WORKSPACE_SLUG') : '';
65
+ // Trello
66
+ console.log('\n ── PM Backend (Trello) ──');
67
+ const trelloApiKey = await prompt.ask('TRELLO_API_KEY (leave empty if not using Trello)');
68
+ const trelloToken = trelloApiKey ? await prompt.ask('TRELLO_TOKEN') : '';
69
+ // Matrix notifications
70
+ console.log('\n ── Notifications (Matrix) ──');
71
+ const matrixHomeserver = await prompt.ask('MATRIX_HOMESERVER (leave empty if not using Matrix)');
72
+ const matrixToken = matrixHomeserver ? await prompt.ask('MATRIX_TOKEN') : '';
73
+ const matrixRoomId = matrixHomeserver ? await prompt.ask('MATRIX_ROOM_ID') : '';
74
+ // Build env file
75
+ const lines = [
76
+ '# SPS CLI — Global Credentials',
77
+ `# Generated by: sps setup (${new Date().toISOString().slice(0, 10)})`,
78
+ '',
79
+ ];
80
+ if (gitlabUrl || gitlabToken) {
81
+ lines.push('# ── GitLab ──────────────────────────────────────────');
82
+ if (gitlabUrl)
83
+ lines.push(`export GITLAB_URL="${gitlabUrl}"`);
84
+ if (gitlabToken)
85
+ lines.push(`export GITLAB_TOKEN="${gitlabToken}"`);
86
+ if (gitlabSshHost)
87
+ lines.push(`export GITLAB_SSH_HOST="${gitlabSshHost}"`);
88
+ if (gitlabSshPort && gitlabSshPort !== '22')
89
+ lines.push(`export GITLAB_SSH_PORT="${gitlabSshPort}"`);
90
+ lines.push('');
91
+ }
92
+ if (planeUrl) {
93
+ lines.push('# ── Plane ───────────────────────────────────────────');
94
+ lines.push(`export PLANE_URL="${planeUrl}"`);
95
+ if (planeApiKey)
96
+ lines.push(`export PLANE_API_KEY="${planeApiKey}"`);
97
+ if (planeWorkspace)
98
+ lines.push(`export PLANE_WORKSPACE_SLUG="${planeWorkspace}"`);
99
+ lines.push('');
100
+ }
101
+ if (trelloApiKey) {
102
+ lines.push('# ── Trello ──────────────────────────────────────────');
103
+ lines.push(`export TRELLO_API_KEY="${trelloApiKey}"`);
104
+ if (trelloToken)
105
+ lines.push(`export TRELLO_TOKEN="${trelloToken}"`);
106
+ lines.push('');
107
+ }
108
+ if (matrixHomeserver) {
109
+ lines.push('# ── Matrix (Notifications) ──────────────────────────');
110
+ lines.push(`export MATRIX_HOMESERVER="${matrixHomeserver}"`);
111
+ if (matrixToken)
112
+ lines.push(`export MATRIX_TOKEN="${matrixToken}"`);
113
+ if (matrixRoomId)
114
+ lines.push(`export MATRIX_ROOM_ID="${matrixRoomId}"`);
115
+ lines.push('');
116
+ }
117
+ writeFileSync(ENV_PATH, lines.join('\n') + '\n');
118
+ chmodSync(ENV_PATH, 0o600);
119
+ log.ok(`Created ${ENV_PATH} (permissions: 600)`);
120
+ }
121
+ // ─── Summary ───────────────────────────────────────────────────
122
+ console.log('\n Setup complete! Next steps:\n');
123
+ console.log(' 1. Source the env file:');
124
+ console.log(` source ${ENV_PATH}`);
125
+ console.log('');
126
+ console.log(' 2. (Optional) Auto-load on shell startup:');
127
+ console.log(` echo 'source ${ENV_PATH}' >> ~/.bashrc`);
128
+ console.log('');
129
+ console.log(' 3. Initialize your first project:');
130
+ console.log(' sps project init <project-name>');
131
+ console.log('');
132
+ console.log(' 4. Edit the project config:');
133
+ console.log(' vim ~/.projects/<project-name>/conf');
134
+ console.log('');
135
+ console.log(' 5. Run health check:');
136
+ console.log(' sps doctor <project-name> --fix');
137
+ console.log('');
138
+ prompt.close();
139
+ }
140
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -9,8 +9,10 @@ import { executeQaTick } from './commands/qaTick.js';
9
9
  import { executeMonitorTick } from './commands/monitorTick.js';
10
10
  import { executePmCommand } from './commands/pmCommand.js';
11
11
  import { executeCardAdd } from './commands/cardAdd.js';
12
- const VERSION = '0.6.0';
12
+ import { executeSetup } from './commands/setup.js';
13
+ const VERSION = '0.7.0';
13
14
  const COMMANDS = {
15
+ setup: { desc: 'Initial environment setup (credentials, directories)', usage: 'sps setup [--force]' },
14
16
  tick: { desc: 'Run continuous pipeline (--once for single tick)', usage: 'sps tick <project> [--once]' },
15
17
  card: { desc: 'Card management', usage: 'sps card add <project> "<title>" ["desc"]' },
16
18
  doctor: { desc: 'Project health check', usage: 'sps doctor <project> [--json] [--skip-remote]' },
@@ -93,6 +95,11 @@ async function main() {
93
95
  printHelp();
94
96
  process.exit(0);
95
97
  }
98
+ // ─── setup ─────────────────────────────────────────────────
99
+ if (args.command === 'setup') {
100
+ await executeSetup(args.flags);
101
+ return;
102
+ }
96
103
  // ─── tick (supports multiple projects) ──────────────────────
97
104
  if (args.command === 'tick') {
98
105
  // Collect all projects: project + positionals
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "SPS CLI — AI-driven development pipeline orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -8,7 +8,7 @@
8
8
  "sps": "dist/main.js"
9
9
  },
10
10
  "scripts": {
11
- "build": "tsc",
11
+ "build": "tsc && cp -r ../project-template ./project-template 2>/dev/null || true",
12
12
  "dev": "tsx src/main.ts",
13
13
  "typecheck": "tsc --noEmit",
14
14
  "prepublishOnly": "npm run build"
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "files": [
20
20
  "dist",
21
+ "project-template",
21
22
  "README.md"
22
23
  ],
23
24
  "keywords": [
@@ -0,0 +1,10 @@
1
+ # Project Template
2
+
3
+ This folder is copied into `~/.projects/<project-name>/` for each new pipeline-managed project.
4
+
5
+ Contents:
6
+ - `conf` — project-specific configuration
7
+ - `deploy.sh` — optional project-local deploy entrypoint
8
+ - `batch_scheduler.sh` — project-local Planning → Backlog scheduler
9
+ - `logs/` — runtime logs
10
+ - `pm_meta/` — local PM metadata store (used especially for Plane)
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env bash
2
+ # batch_scheduler.sh — project-local sequential scheduler (Planning → Backlog)
3
+ set -euo pipefail
4
+
5
+ PROJECT_NAME="$(basename "$(cd "$(dirname "$0")" && pwd)")"
6
+ source ~/.jarvis.env
7
+ source "$HOME/.projects/$PROJECT_NAME/conf"
8
+
9
+ MPOST="bash $HOME/jarvis-skills/coding-work-flow/scripts/notify.sh"
10
+ LOG="$HOME/.projects/$PROJECT_NAME/logs/batch_scheduler.log"
11
+ mkdir -p "$(dirname "$LOG")"
12
+ log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
13
+
14
+ if [ "${PM_TOOL:-trello}" = "trello" ]; then
15
+ TAPI="https://api.trello.com/1"
16
+ TQ="key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"
17
+ : "${TRELLO_LIST_PLANNING:?Missing TRELLO_LIST_PLANNING}"
18
+ : "${TRELLO_LIST_BACKLOG:?Missing TRELLO_LIST_BACKLOG}"
19
+ : "${TRELLO_LIST_TODO:?Missing TRELLO_LIST_TODO}"
20
+ : "${TRELLO_LIST_INPROGRESS:?Missing TRELLO_LIST_INPROGRESS}"
21
+ : "${TRELLO_LIST_QA:?Missing TRELLO_LIST_QA}"
22
+
23
+ active=$(python3 - <<PY
24
+ import urllib.request, json
25
+ lists=['$TRELLO_LIST_BACKLOG','$TRELLO_LIST_TODO','$TRELLO_LIST_INPROGRESS','$TRELLO_LIST_QA']
26
+ label='${PIPELINE_LABEL:-}'
27
+ total=0
28
+ for l in lists:
29
+ url=f'$TAPI/lists/{l}/cards?$TQ&fields=id,name,labels'
30
+ cards=json.loads(urllib.request.urlopen(url).read())
31
+ if label:
32
+ total += sum(1 for c in cards if any((lb.get('name') or '').strip()==label for lb in c.get('labels',[])))
33
+ else:
34
+ total += len(cards)
35
+ print(total)
36
+ PY
37
+ )
38
+ log "Active pipeline tasks: $active"
39
+ if [ "$active" -gt 0 ]; then
40
+ log "Pipeline still busy, skip promotion"
41
+ exit 0
42
+ fi
43
+
44
+ next=$(PIPELINE_LABEL="${PIPELINE_LABEL:-}" TRELLO_JSON="$(curl -s "$TAPI/lists/$TRELLO_LIST_PLANNING/cards?$TQ&fields=id,name,labels,pos")" python3 - <<'PY'
45
+ import json,os
46
+ label=os.environ.get('PIPELINE_LABEL','').strip()
47
+ obj=json.loads(os.environ.get('TRELLO_JSON','[]'))
48
+ items=[]
49
+ for c in obj:
50
+ labels=[(lb.get('name') or '').strip() for lb in c.get('labels',[])]
51
+ if label and label not in labels:
52
+ continue
53
+ items.append((c.get('pos', 10**18), c.get('id',''), c.get('name','')))
54
+ items.sort()
55
+ if items:
56
+ _, cid, name = items[0]
57
+ print(f"{cid}|{name}")
58
+ PY
59
+ )
60
+ [ -z "$next" ] && { log "Planning empty, nothing to promote"; exit 0; }
61
+ card_id="${next%%|*}"
62
+ card_name="${next#*|}"
63
+ curl -sf -X PUT "$TAPI/cards/$card_id?$TQ" -d "idList=$TRELLO_LIST_BACKLOG" > /dev/null
64
+ log "Promoted: $card_name → Backlog"
65
+ $MPOST "🚀 [$PROJECT_NAME] 推进任务:$card_name" >/dev/null 2>&1 || true
66
+ exit 0
67
+ fi
68
+
69
+ HELPER="${PLANE_HELPER:-$HOME/.openclaw/workspace/skills/plane/scripts/plane_helper.py}"
70
+ : "${PLANE_PROJECT_ID:?Missing PLANE_PROJECT_ID}"
71
+ : "${PLANE_STATE_PLANNING:?Missing PLANE_STATE_PLANNING}"
72
+ : "${PLANE_STATE_BACKLOG:?Missing PLANE_STATE_BACKLOG}"
73
+ : "${PLANE_STATE_TODO:?Missing PLANE_STATE_TODO}"
74
+ : "${PLANE_STATE_INPROGRESS:?Missing PLANE_STATE_INPROGRESS}"
75
+ : "${PLANE_STATE_QA:?Missing PLANE_STATE_QA}"
76
+
77
+ active=$(ACTIVE_STATE_IDS="$PLANE_STATE_BACKLOG,$PLANE_STATE_TODO,$PLANE_STATE_INPROGRESS,$PLANE_STATE_QA" PIPELINE_LABEL="${PIPELINE_LABEL:-}" PIPELINE_MIN_SEQ="${PIPELINE_MIN_SEQ:-}" LABELS_JSON="$(python3 "$HELPER" labels list "$PLANE_PROJECT_ID" 2>/dev/null)" PLANE_JSON="$(python3 "$HELPER" issues list "$PLANE_PROJECT_ID" 2>/dev/null)" python3 - <<'PY'
78
+ import json,os
79
+ obj=json.loads(os.environ['PLANE_JSON'])
80
+ active=set(filter(None, os.environ.get('ACTIVE_STATE_IDS','').split(',')))
81
+ want=os.environ.get('PIPELINE_LABEL','').strip()
82
+ min_seq=(os.environ.get('PIPELINE_MIN_SEQ') or '').strip()
83
+ count=0
84
+ label_map={x.get('id'): x.get('name','') for x in json.loads(os.environ.get('LABELS_JSON','{"results":[]}')).get('results',[])}
85
+ for it in obj.get('results',[]):
86
+ if it.get('state') not in active:
87
+ continue
88
+ labels=[]
89
+ for lb in it.get('labels',[]):
90
+ if isinstance(lb, dict):
91
+ name=(lb.get('name') or '').strip()
92
+ else:
93
+ name=(label_map.get(lb,'') or '').strip()
94
+ if name:
95
+ labels.append(name)
96
+ if want and want not in labels:
97
+ continue
98
+ if min_seq:
99
+ try:
100
+ if int(it.get('sequence_id') or 0) < int(min_seq):
101
+ continue
102
+ except Exception:
103
+ pass
104
+ count += 1
105
+ print(count)
106
+ PY
107
+ )
108
+ log "Active pipeline tasks: $active"
109
+ if [ "$active" -gt 0 ]; then
110
+ log "Pipeline still busy, skip promotion"
111
+ exit 0
112
+ fi
113
+
114
+ next=$(PIPELINE_LABEL="${PIPELINE_LABEL:-}" PIPELINE_ORDER_FILE="${PIPELINE_ORDER_FILE:-}" LABELS_JSON="$(python3 "$HELPER" labels list "$PLANE_PROJECT_ID" 2>/dev/null)" PLANE_JSON="$(python3 "$HELPER" issues list "$PLANE_PROJECT_ID" "$PLANE_STATE_PLANNING" 2>/dev/null)" python3 - <<'PY'
115
+ import json,os
116
+ obj=json.loads(os.environ['PLANE_JSON'])
117
+ label_map={x.get('id'): x.get('name','') for x in json.loads(os.environ.get('LABELS_JSON','{"results":[]}')).get('results',[])}
118
+ want=os.environ.get('PIPELINE_LABEL','').strip()
119
+ order_file=(os.environ.get('PIPELINE_ORDER_FILE') or '').strip()
120
+ seq_order=[]
121
+ if order_file and os.path.exists(order_file):
122
+ try:
123
+ raw=json.load(open(order_file))
124
+ if isinstance(raw, list):
125
+ seq_order=[int(x) for x in raw]
126
+ else:
127
+ seq_order=[int(x) for x in raw.get('items',[])]
128
+ except Exception:
129
+ seq_order=[]
130
+ items_by_seq={}
131
+ for it in obj.get('results',[]):
132
+ labels=[]
133
+ for lb in it.get('labels',[]):
134
+ if isinstance(lb, dict):
135
+ name=(lb.get('name') or '').strip()
136
+ else:
137
+ name=(label_map.get(lb,'') or '').strip()
138
+ if name:
139
+ labels.append(name)
140
+ if want and want not in labels:
141
+ continue
142
+ try:
143
+ seq_num=int(it.get('sequence_id') or 0)
144
+ except Exception:
145
+ continue
146
+ items_by_seq[seq_num]=(it.get('id',''), it.get('name',''))
147
+ if seq_order:
148
+ for seq in seq_order:
149
+ if seq in items_by_seq:
150
+ iid,name=items_by_seq[seq]
151
+ print(f"{iid}|{name}")
152
+ raise SystemExit(0)
153
+ else:
154
+ for seq in sorted(items_by_seq):
155
+ iid,name=items_by_seq[seq]
156
+ print(f"{iid}|{name}")
157
+ raise SystemExit(0)
158
+ PY
159
+ )
160
+ [ -z "$next" ] && { log "Planning empty, nothing to promote"; exit 0; }
161
+ issue_id="${next%%|*}"
162
+ issue_name="${next#*|}"
163
+ python3 "$HELPER" issues move "$PLANE_PROJECT_ID" "$issue_id" "$PLANE_STATE_BACKLOG" >/dev/null
164
+ log "Promoted: $issue_name → Backlog"
165
+ $MPOST "🚀 [$PROJECT_NAME] 推进任务:$issue_name" >/dev/null 2>&1 || true
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ # batch_scheduler.sh — project-local cron entry point
3
+ # Delegates to the unified workflow CLI tick command.
4
+ # All scheduling, pipeline, QA, and monitor logic lives in the Node CLI.
5
+ set -euo pipefail
6
+
7
+ PROJECT_NAME="$(basename "$(cd "$(dirname "$0")" && pwd)")"
8
+ WORKFLOW_CLI="$HOME/jarvis-skills/coding-work-flow/bin/workflow"
9
+
10
+ exec "$WORKFLOW_CLI" tick "$PROJECT_NAME" "$@"
@@ -0,0 +1,73 @@
1
+ # ── 项目基础信息 ─────────────────────────────────────────────────
2
+ export PROJECT_NAME="__PROJECT_NAME__"
3
+ export PROJECT_DISPLAY="__PROJECT_DISPLAY__"
4
+ export PROJECT_DIR="$HOME/projects/__PROJECT_NAME__"
5
+
6
+ # ── GitLab ───────────────────────────────────────────────────────
7
+ export GITLAB_PROJECT="__GITLAB_PROJECT__"
8
+ export GITLAB_PROJECT_ID="__GITLAB_PROJECT_ID__"
9
+ export GITLAB_MERGE_BRANCH="__GITLAB_MERGE_BRANCH__"
10
+ export GITLAB_RELEASE_BRANCH="__GITLAB_RELEASE_BRANCH__"
11
+
12
+ # ── PM Backend ───────────────────────────────────────────────────
13
+ export PM_TOOL="__PM_TOOL__"
14
+
15
+ # ── Trello(PM_TOOL=trello 时填写)───────────────────────────────
16
+ export TRELLO_BOARD_ID="__TRELLO_BOARD_ID__"
17
+ export TRELLO_LIST_PLANNING="__TRELLO_LIST_PLANNING__"
18
+ export TRELLO_LIST_BACKLOG="__TRELLO_LIST_BACKLOG__"
19
+ export TRELLO_LIST_TODO="__TRELLO_LIST_TODO__"
20
+ export TRELLO_LIST_INPROGRESS="__TRELLO_LIST_INPROGRESS__"
21
+ export TRELLO_LIST_QA="__TRELLO_LIST_QA__"
22
+ export TRELLO_LIST_DONE="__TRELLO_LIST_DONE__"
23
+ export TRELLO_ACCOUNT="__TRELLO_ACCOUNT__"
24
+
25
+ # ── Plane(PM_TOOL=plane 时填写)────────────────────────────────
26
+ export PLANE_API_URL="__PLANE_API_URL__"
27
+ export PLANE_API_KEY="__PLANE_API_KEY__"
28
+ export PLANE_WORKSPACE_SLUG="__PLANE_WORKSPACE_SLUG__"
29
+ export PLANE_PROJECT_ID="__PLANE_PROJECT_ID__"
30
+ export PLANE_PROJECT_NAME="__PLANE_PROJECT_NAME__"
31
+ export PLANE_STATE_PLANNING="__PLANE_STATE_PLANNING__"
32
+ export PLANE_STATE_BACKLOG="__PLANE_STATE_BACKLOG__"
33
+ export PLANE_STATE_TODO="__PLANE_STATE_TODO__"
34
+ export PLANE_STATE_INPROGRESS="__PLANE_STATE_INPROGRESS__"
35
+ export PLANE_STATE_QA="__PLANE_STATE_QA__"
36
+ export PLANE_STATE_DONE="__PLANE_STATE_DONE__"
37
+ export PLANE_STATE_CANCELLED="__PLANE_STATE_CANCELLED__"
38
+
39
+ # ── Pipeline 筛选(可选)────────────────────────────────────────
40
+ export PIPELINE_LABEL="__PIPELINE_LABEL__"
41
+ export PIPELINE_ORDER_FILE="$HOME/.projects/__PROJECT_NAME__/pipeline_order.json"
42
+
43
+ # ── CI ───────────────────────────────────────────────────────────
44
+ export CI_MODE="__CI_MODE__"
45
+
46
+ # ── 前端构建 ─────────────────────────────────────────────────────
47
+ export HAS_FRONTEND="__HAS_FRONTEND__"
48
+ export FRONTEND_DIR="__FRONTEND_DIR__"
49
+
50
+ # ── 部署 ─────────────────────────────────────────────────────────
51
+ export DEPLOY_ENABLED="__DEPLOY_ENABLED__"
52
+ export DEPLOY_SCRIPT="$HOME/.projects/__PROJECT_NAME__/deploy.sh"
53
+
54
+ # ── Worker / Agent ───────────────────────────────────────────────
55
+ export WORKER_TOOL="__WORKER_TOOL__"
56
+ export MAX_CONCURRENT_WORKERS=__MAX_CONCURRENT_WORKERS__
57
+ export WORKER_RESTART_LIMIT=__WORKER_RESTART_LIMIT__
58
+ export AUTOFIX_ATTEMPTS=__AUTOFIX_ATTEMPTS__
59
+ export WORKER_SESSION_REUSE=true
60
+ export MAX_ACTIONS_PER_TICK=1
61
+
62
+ # ── 超时与策略 ───────────────────────────────────────────────────
63
+ export INPROGRESS_TIMEOUT_HOURS=8
64
+ export MONITOR_AUTO_QA=false
65
+ export CONFLICT_DEFAULT=serial
66
+ export TICK_LOCK_TIMEOUT_MINUTES=30
67
+ export NEEDS_FIX_MAX_RETRIES=3
68
+ export WORKTREE_RETAIN_HOURS=24
69
+
70
+ # ── 通知(Matrix)──────────────────────────────────────────────
71
+ export MATRIX_HOMESERVER="__MATRIX_HOMESERVER__"
72
+ export MATRIX_ACCESS_TOKEN="__MATRIX_ACCESS_TOKEN__"
73
+ export MATRIX_ROOM_ID="__MATRIX_ROOM_ID__"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ echo "Deployment not configured for ${PROJECT_NAME:-unknown-project}"
File without changes
File without changes
@@ -0,0 +1,10 @@
1
+ # Project Template
2
+
3
+ This folder is copied into `~/.projects/<project-name>/` for each new pipeline-managed project.
4
+
5
+ Contents:
6
+ - `conf` — project-specific configuration
7
+ - `deploy.sh` — optional project-local deploy entrypoint
8
+ - `batch_scheduler.sh` — project-local Planning → Backlog scheduler
9
+ - `logs/` — runtime logs
10
+ - `pm_meta/` — local PM metadata store (used especially for Plane)
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env bash
2
+ # batch_scheduler.sh — project-local sequential scheduler (Planning → Backlog)
3
+ set -euo pipefail
4
+
5
+ PROJECT_NAME="$(basename "$(cd "$(dirname "$0")" && pwd)")"
6
+ source ~/.jarvis.env
7
+ source "$HOME/.projects/$PROJECT_NAME/conf"
8
+
9
+ MPOST="bash $HOME/jarvis-skills/coding-work-flow/scripts/notify.sh"
10
+ LOG="$HOME/.projects/$PROJECT_NAME/logs/batch_scheduler.log"
11
+ mkdir -p "$(dirname "$LOG")"
12
+ log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
13
+
14
+ if [ "${PM_TOOL:-trello}" = "trello" ]; then
15
+ TAPI="https://api.trello.com/1"
16
+ TQ="key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"
17
+ : "${TRELLO_LIST_PLANNING:?Missing TRELLO_LIST_PLANNING}"
18
+ : "${TRELLO_LIST_BACKLOG:?Missing TRELLO_LIST_BACKLOG}"
19
+ : "${TRELLO_LIST_TODO:?Missing TRELLO_LIST_TODO}"
20
+ : "${TRELLO_LIST_INPROGRESS:?Missing TRELLO_LIST_INPROGRESS}"
21
+ : "${TRELLO_LIST_QA:?Missing TRELLO_LIST_QA}"
22
+
23
+ active=$(python3 - <<PY
24
+ import urllib.request, json
25
+ lists=['$TRELLO_LIST_BACKLOG','$TRELLO_LIST_TODO','$TRELLO_LIST_INPROGRESS','$TRELLO_LIST_QA']
26
+ label='${PIPELINE_LABEL:-}'
27
+ total=0
28
+ for l in lists:
29
+ url=f'$TAPI/lists/{l}/cards?$TQ&fields=id,name,labels'
30
+ cards=json.loads(urllib.request.urlopen(url).read())
31
+ if label:
32
+ total += sum(1 for c in cards if any((lb.get('name') or '').strip()==label for lb in c.get('labels',[])))
33
+ else:
34
+ total += len(cards)
35
+ print(total)
36
+ PY
37
+ )
38
+ log "Active pipeline tasks: $active"
39
+ if [ "$active" -gt 0 ]; then
40
+ log "Pipeline still busy, skip promotion"
41
+ exit 0
42
+ fi
43
+
44
+ next=$(PIPELINE_LABEL="${PIPELINE_LABEL:-}" TRELLO_JSON="$(curl -s "$TAPI/lists/$TRELLO_LIST_PLANNING/cards?$TQ&fields=id,name,labels,pos")" python3 - <<'PY'
45
+ import json,os
46
+ label=os.environ.get('PIPELINE_LABEL','').strip()
47
+ obj=json.loads(os.environ.get('TRELLO_JSON','[]'))
48
+ items=[]
49
+ for c in obj:
50
+ labels=[(lb.get('name') or '').strip() for lb in c.get('labels',[])]
51
+ if label and label not in labels:
52
+ continue
53
+ items.append((c.get('pos', 10**18), c.get('id',''), c.get('name','')))
54
+ items.sort()
55
+ if items:
56
+ _, cid, name = items[0]
57
+ print(f"{cid}|{name}")
58
+ PY
59
+ )
60
+ [ -z "$next" ] && { log "Planning empty, nothing to promote"; exit 0; }
61
+ card_id="${next%%|*}"
62
+ card_name="${next#*|}"
63
+ curl -sf -X PUT "$TAPI/cards/$card_id?$TQ" -d "idList=$TRELLO_LIST_BACKLOG" > /dev/null
64
+ log "Promoted: $card_name → Backlog"
65
+ $MPOST "🚀 [$PROJECT_NAME] 推进任务:$card_name" >/dev/null 2>&1 || true
66
+ exit 0
67
+ fi
68
+
69
+ HELPER="${PLANE_HELPER:-$HOME/.openclaw/workspace/skills/plane/scripts/plane_helper.py}"
70
+ : "${PLANE_PROJECT_ID:?Missing PLANE_PROJECT_ID}"
71
+ : "${PLANE_STATE_PLANNING:?Missing PLANE_STATE_PLANNING}"
72
+ : "${PLANE_STATE_BACKLOG:?Missing PLANE_STATE_BACKLOG}"
73
+ : "${PLANE_STATE_TODO:?Missing PLANE_STATE_TODO}"
74
+ : "${PLANE_STATE_INPROGRESS:?Missing PLANE_STATE_INPROGRESS}"
75
+ : "${PLANE_STATE_QA:?Missing PLANE_STATE_QA}"
76
+
77
+ active=$(ACTIVE_STATE_IDS="$PLANE_STATE_BACKLOG,$PLANE_STATE_TODO,$PLANE_STATE_INPROGRESS,$PLANE_STATE_QA" PIPELINE_LABEL="${PIPELINE_LABEL:-}" PIPELINE_MIN_SEQ="${PIPELINE_MIN_SEQ:-}" LABELS_JSON="$(python3 "$HELPER" labels list "$PLANE_PROJECT_ID" 2>/dev/null)" PLANE_JSON="$(python3 "$HELPER" issues list "$PLANE_PROJECT_ID" 2>/dev/null)" python3 - <<'PY'
78
+ import json,os
79
+ obj=json.loads(os.environ['PLANE_JSON'])
80
+ active=set(filter(None, os.environ.get('ACTIVE_STATE_IDS','').split(',')))
81
+ want=os.environ.get('PIPELINE_LABEL','').strip()
82
+ min_seq=(os.environ.get('PIPELINE_MIN_SEQ') or '').strip()
83
+ count=0
84
+ label_map={x.get('id'): x.get('name','') for x in json.loads(os.environ.get('LABELS_JSON','{"results":[]}')).get('results',[])}
85
+ for it in obj.get('results',[]):
86
+ if it.get('state') not in active:
87
+ continue
88
+ labels=[]
89
+ for lb in it.get('labels',[]):
90
+ if isinstance(lb, dict):
91
+ name=(lb.get('name') or '').strip()
92
+ else:
93
+ name=(label_map.get(lb,'') or '').strip()
94
+ if name:
95
+ labels.append(name)
96
+ if want and want not in labels:
97
+ continue
98
+ if min_seq:
99
+ try:
100
+ if int(it.get('sequence_id') or 0) < int(min_seq):
101
+ continue
102
+ except Exception:
103
+ pass
104
+ count += 1
105
+ print(count)
106
+ PY
107
+ )
108
+ log "Active pipeline tasks: $active"
109
+ if [ "$active" -gt 0 ]; then
110
+ log "Pipeline still busy, skip promotion"
111
+ exit 0
112
+ fi
113
+
114
+ next=$(PIPELINE_LABEL="${PIPELINE_LABEL:-}" PIPELINE_ORDER_FILE="${PIPELINE_ORDER_FILE:-}" LABELS_JSON="$(python3 "$HELPER" labels list "$PLANE_PROJECT_ID" 2>/dev/null)" PLANE_JSON="$(python3 "$HELPER" issues list "$PLANE_PROJECT_ID" "$PLANE_STATE_PLANNING" 2>/dev/null)" python3 - <<'PY'
115
+ import json,os
116
+ obj=json.loads(os.environ['PLANE_JSON'])
117
+ label_map={x.get('id'): x.get('name','') for x in json.loads(os.environ.get('LABELS_JSON','{"results":[]}')).get('results',[])}
118
+ want=os.environ.get('PIPELINE_LABEL','').strip()
119
+ order_file=(os.environ.get('PIPELINE_ORDER_FILE') or '').strip()
120
+ seq_order=[]
121
+ if order_file and os.path.exists(order_file):
122
+ try:
123
+ raw=json.load(open(order_file))
124
+ if isinstance(raw, list):
125
+ seq_order=[int(x) for x in raw]
126
+ else:
127
+ seq_order=[int(x) for x in raw.get('items',[])]
128
+ except Exception:
129
+ seq_order=[]
130
+ items_by_seq={}
131
+ for it in obj.get('results',[]):
132
+ labels=[]
133
+ for lb in it.get('labels',[]):
134
+ if isinstance(lb, dict):
135
+ name=(lb.get('name') or '').strip()
136
+ else:
137
+ name=(label_map.get(lb,'') or '').strip()
138
+ if name:
139
+ labels.append(name)
140
+ if want and want not in labels:
141
+ continue
142
+ try:
143
+ seq_num=int(it.get('sequence_id') or 0)
144
+ except Exception:
145
+ continue
146
+ items_by_seq[seq_num]=(it.get('id',''), it.get('name',''))
147
+ if seq_order:
148
+ for seq in seq_order:
149
+ if seq in items_by_seq:
150
+ iid,name=items_by_seq[seq]
151
+ print(f"{iid}|{name}")
152
+ raise SystemExit(0)
153
+ else:
154
+ for seq in sorted(items_by_seq):
155
+ iid,name=items_by_seq[seq]
156
+ print(f"{iid}|{name}")
157
+ raise SystemExit(0)
158
+ PY
159
+ )
160
+ [ -z "$next" ] && { log "Planning empty, nothing to promote"; exit 0; }
161
+ issue_id="${next%%|*}"
162
+ issue_name="${next#*|}"
163
+ python3 "$HELPER" issues move "$PLANE_PROJECT_ID" "$issue_id" "$PLANE_STATE_BACKLOG" >/dev/null
164
+ log "Promoted: $issue_name → Backlog"
165
+ $MPOST "🚀 [$PROJECT_NAME] 推进任务:$issue_name" >/dev/null 2>&1 || true
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ # batch_scheduler.sh — project-local cron entry point
3
+ # Delegates to the unified workflow CLI tick command.
4
+ # All scheduling, pipeline, QA, and monitor logic lives in the Node CLI.
5
+ set -euo pipefail
6
+
7
+ PROJECT_NAME="$(basename "$(cd "$(dirname "$0")" && pwd)")"
8
+ WORKFLOW_CLI="$HOME/jarvis-skills/coding-work-flow/bin/workflow"
9
+
10
+ exec "$WORKFLOW_CLI" tick "$PROJECT_NAME" "$@"
@@ -0,0 +1,73 @@
1
+ # ── 项目基础信息 ─────────────────────────────────────────────────
2
+ export PROJECT_NAME="__PROJECT_NAME__"
3
+ export PROJECT_DISPLAY="__PROJECT_DISPLAY__"
4
+ export PROJECT_DIR="$HOME/projects/__PROJECT_NAME__"
5
+
6
+ # ── GitLab ───────────────────────────────────────────────────────
7
+ export GITLAB_PROJECT="__GITLAB_PROJECT__"
8
+ export GITLAB_PROJECT_ID="__GITLAB_PROJECT_ID__"
9
+ export GITLAB_MERGE_BRANCH="__GITLAB_MERGE_BRANCH__"
10
+ export GITLAB_RELEASE_BRANCH="__GITLAB_RELEASE_BRANCH__"
11
+
12
+ # ── PM Backend ───────────────────────────────────────────────────
13
+ export PM_TOOL="__PM_TOOL__"
14
+
15
+ # ── Trello(PM_TOOL=trello 时填写)───────────────────────────────
16
+ export TRELLO_BOARD_ID="__TRELLO_BOARD_ID__"
17
+ export TRELLO_LIST_PLANNING="__TRELLO_LIST_PLANNING__"
18
+ export TRELLO_LIST_BACKLOG="__TRELLO_LIST_BACKLOG__"
19
+ export TRELLO_LIST_TODO="__TRELLO_LIST_TODO__"
20
+ export TRELLO_LIST_INPROGRESS="__TRELLO_LIST_INPROGRESS__"
21
+ export TRELLO_LIST_QA="__TRELLO_LIST_QA__"
22
+ export TRELLO_LIST_DONE="__TRELLO_LIST_DONE__"
23
+ export TRELLO_ACCOUNT="__TRELLO_ACCOUNT__"
24
+
25
+ # ── Plane(PM_TOOL=plane 时填写)────────────────────────────────
26
+ export PLANE_API_URL="__PLANE_API_URL__"
27
+ export PLANE_API_KEY="__PLANE_API_KEY__"
28
+ export PLANE_WORKSPACE_SLUG="__PLANE_WORKSPACE_SLUG__"
29
+ export PLANE_PROJECT_ID="__PLANE_PROJECT_ID__"
30
+ export PLANE_PROJECT_NAME="__PLANE_PROJECT_NAME__"
31
+ export PLANE_STATE_PLANNING="__PLANE_STATE_PLANNING__"
32
+ export PLANE_STATE_BACKLOG="__PLANE_STATE_BACKLOG__"
33
+ export PLANE_STATE_TODO="__PLANE_STATE_TODO__"
34
+ export PLANE_STATE_INPROGRESS="__PLANE_STATE_INPROGRESS__"
35
+ export PLANE_STATE_QA="__PLANE_STATE_QA__"
36
+ export PLANE_STATE_DONE="__PLANE_STATE_DONE__"
37
+ export PLANE_STATE_CANCELLED="__PLANE_STATE_CANCELLED__"
38
+
39
+ # ── Pipeline 筛选(可选)────────────────────────────────────────
40
+ export PIPELINE_LABEL="__PIPELINE_LABEL__"
41
+ export PIPELINE_ORDER_FILE="$HOME/.projects/__PROJECT_NAME__/pipeline_order.json"
42
+
43
+ # ── CI ───────────────────────────────────────────────────────────
44
+ export CI_MODE="__CI_MODE__"
45
+
46
+ # ── 前端构建 ─────────────────────────────────────────────────────
47
+ export HAS_FRONTEND="__HAS_FRONTEND__"
48
+ export FRONTEND_DIR="__FRONTEND_DIR__"
49
+
50
+ # ── 部署 ─────────────────────────────────────────────────────────
51
+ export DEPLOY_ENABLED="__DEPLOY_ENABLED__"
52
+ export DEPLOY_SCRIPT="$HOME/.projects/__PROJECT_NAME__/deploy.sh"
53
+
54
+ # ── Worker / Agent ───────────────────────────────────────────────
55
+ export WORKER_TOOL="__WORKER_TOOL__"
56
+ export MAX_CONCURRENT_WORKERS=__MAX_CONCURRENT_WORKERS__
57
+ export WORKER_RESTART_LIMIT=__WORKER_RESTART_LIMIT__
58
+ export AUTOFIX_ATTEMPTS=__AUTOFIX_ATTEMPTS__
59
+ export WORKER_SESSION_REUSE=true
60
+ export MAX_ACTIONS_PER_TICK=1
61
+
62
+ # ── 超时与策略 ───────────────────────────────────────────────────
63
+ export INPROGRESS_TIMEOUT_HOURS=8
64
+ export MONITOR_AUTO_QA=false
65
+ export CONFLICT_DEFAULT=serial
66
+ export TICK_LOCK_TIMEOUT_MINUTES=30
67
+ export NEEDS_FIX_MAX_RETRIES=3
68
+ export WORKTREE_RETAIN_HOURS=24
69
+
70
+ # ── 通知(Matrix)──────────────────────────────────────────────
71
+ export MATRIX_HOMESERVER="__MATRIX_HOMESERVER__"
72
+ export MATRIX_ACCESS_TOKEN="__MATRIX_ACCESS_TOKEN__"
73
+ export MATRIX_ROOM_ID="__MATRIX_ROOM_ID__"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ echo "Deployment not configured for ${PROJECT_NAME:-unknown-project}"