@leejungkiin/awkit 1.2.0 → 1.3.4
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/bin/awf.js +0 -1
- package/bin/awk.js +309 -68
- package/core/GEMINI.md +19 -5
- package/package.json +3 -4
- package/skills/CATALOG.md +4 -0
- package/skills/GEMINI.md +158 -0
- package/skills/brainstorm-agent/SKILL.md +44 -11
- package/skills/ios-engineer/SKILL.md +4 -0
- package/skills/module-spec-writer/SKILL.md +459 -0
- package/skills/module-spec-writer/module-spec-writer/SKILL.md +414 -0
- package/skills/orchestrator/SKILL.md +178 -19
- package/skills/spec-gate/SKILL.md +39 -10
- package/skills/symphony-enforcer/SKILL.md +40 -22
- package/skills/trello-sync/SKILL.md +214 -0
- package/skills/verification-gate/SKILL.md +2 -0
- package/skills/visual-design-gate/SKILL.md +177 -0
- package/templates/configs/trello-config.json +5 -0
- package/VERSION +0 -1
package/bin/awf.js
CHANGED
|
@@ -275,7 +275,6 @@ function cmdInstall() {
|
|
|
275
275
|
dim(`Templates: ${path.join(target, 'templates')}`);
|
|
276
276
|
dim(`GEMINI.md: ${TARGETS.geminiMd}`);
|
|
277
277
|
log('');
|
|
278
|
-
log(`${C.cyan}👉 Type '/plan' in your AI chat to get started.${C.reset}`);
|
|
279
278
|
log(`${C.cyan}👉 Run 'awf doctor' to verify installation.${C.reset}`);
|
|
280
279
|
log('');
|
|
281
280
|
}
|
package/bin/awk.js
CHANGED
|
@@ -28,7 +28,8 @@ const path = require('path');
|
|
|
28
28
|
const https = require('https');
|
|
29
29
|
const { execSync, spawnSync } = require('child_process');
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const packageJson = require(path.join(__dirname, '..', 'package.json'));
|
|
32
|
+
const AWK_VERSION = packageJson.version;
|
|
32
33
|
const AWK_ROOT = path.join(__dirname, '..');
|
|
33
34
|
const HOME = process.env.HOME || process.env.USERPROFILE;
|
|
34
35
|
|
|
@@ -454,10 +455,7 @@ function cmdInstall(platformArg) {
|
|
|
454
455
|
log('');
|
|
455
456
|
|
|
456
457
|
if (platform === 'antigravity') {
|
|
457
|
-
log(`${C.cyan}👉 Type '/plan' in your AI chat to get started.${C.reset}`);
|
|
458
458
|
log(`${C.cyan}👉 Run 'awkit init' in any project to initialize it.${C.reset}`);
|
|
459
|
-
} else if (platform === 'cline') {
|
|
460
|
-
log(`${C.cyan}👉 Type '/plan' in Cline chat to get started.${C.reset}`);
|
|
461
459
|
} else if (platform === 'codex') {
|
|
462
460
|
log(`${C.cyan}👉 Type '$skill' in Codex to invoke skills.${C.reset}`);
|
|
463
461
|
}
|
|
@@ -1371,6 +1369,18 @@ function cmdHelp() {
|
|
|
1371
1369
|
log(` ${C.green}disable-pack${C.reset} <name> Uninstall a skill pack (backed up)`);
|
|
1372
1370
|
log('');
|
|
1373
1371
|
|
|
1372
|
+
// Trello
|
|
1373
|
+
log(`${C.bold}📋 Trello${C.reset}`);
|
|
1374
|
+
log(line);
|
|
1375
|
+
log(` ${C.green}trello desc${C.reset} <text> Update card description`);
|
|
1376
|
+
log(` ${C.green}trello comment${C.reset} <text> Add milestone comment`);
|
|
1377
|
+
log(` ${C.green}trello item${C.reset} <name> Add checklist item`);
|
|
1378
|
+
log(` ${C.green}trello complete${C.reset} <name> Mark checklist item ✅`);
|
|
1379
|
+
log(` ${C.green}trello block${C.reset} <reason> Label card Blocked + comment`);
|
|
1380
|
+
log(` ${C.green}trello checklist${C.reset} <name> Create new checklist`);
|
|
1381
|
+
log(` ${C.gray} Auto-loads .trello-config.json + global credentials${C.reset}`);
|
|
1382
|
+
log('');
|
|
1383
|
+
|
|
1374
1384
|
// Telegram
|
|
1375
1385
|
log(`${C.bold}📨 Telegram${C.reset}`);
|
|
1376
1386
|
log(line);
|
|
@@ -1719,7 +1729,7 @@ function buildCodebaseMd(projectName, projectType, identity) {
|
|
|
1719
1729
|
* CODEBASE.md
|
|
1720
1730
|
* .symphony/ (via Symphony)
|
|
1721
1731
|
*/
|
|
1722
|
-
function cmdInit(forceFlag = false) {
|
|
1732
|
+
async function cmdInit(forceFlag = false) {
|
|
1723
1733
|
const cwd = process.cwd();
|
|
1724
1734
|
const dirName = path.basename(cwd);
|
|
1725
1735
|
// Convert dir name to PascalCase project name: my-app → MyApp, fitbite → Fitbite
|
|
@@ -1773,6 +1783,75 @@ function cmdInit(forceFlag = false) {
|
|
|
1773
1783
|
ok(`${workspaceName} created`);
|
|
1774
1784
|
}
|
|
1775
1785
|
|
|
1786
|
+
// ── 3.5. .trello-config.json ───────────────────────────────────────────────
|
|
1787
|
+
const trelloConfigPath = path.join(cwd, '.trello-config.json');
|
|
1788
|
+
if (fs.existsSync(trelloConfigPath) && !forceFlag) {
|
|
1789
|
+
warn('.trello-config.json already exists — skipping (use --force to overwrite)');
|
|
1790
|
+
} else {
|
|
1791
|
+
info('Creating .trello-config.json...');
|
|
1792
|
+
const templatePath = path.join(TARGETS.antigravity, 'templates', 'configs', 'trello-config.json');
|
|
1793
|
+
if (fs.existsSync(templatePath)) {
|
|
1794
|
+
fs.copyFileSync(templatePath, trelloConfigPath);
|
|
1795
|
+
ok('.trello-config.json created from template');
|
|
1796
|
+
} else {
|
|
1797
|
+
const defaultTrelloConfig = {
|
|
1798
|
+
"BOARD_NAME": "Your Board Name",
|
|
1799
|
+
"LIST_NAME": "Your Backlog List",
|
|
1800
|
+
"CARD_NAME": "Project Card Name or ID"
|
|
1801
|
+
};
|
|
1802
|
+
fs.writeFileSync(trelloConfigPath, JSON.stringify(defaultTrelloConfig, null, 2) + '\n');
|
|
1803
|
+
ok('.trello-config.json created with default values');
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
const trelloCred = trelloLoadCredentials();
|
|
1808
|
+
if (!trelloCred) {
|
|
1809
|
+
log('');
|
|
1810
|
+
warn('Trello API Key & Token are not set.');
|
|
1811
|
+
log(` 👉 To setup Trello integration, please get your credentials at: https://trello.com/app-key`);
|
|
1812
|
+
|
|
1813
|
+
const readline = require('readline');
|
|
1814
|
+
const rl = readline.createInterface({
|
|
1815
|
+
input: process.stdin,
|
|
1816
|
+
output: process.stdout
|
|
1817
|
+
});
|
|
1818
|
+
|
|
1819
|
+
const question = (query) => new Promise(resolve => rl.question(query, resolve));
|
|
1820
|
+
|
|
1821
|
+
try {
|
|
1822
|
+
const apiKey = (await question(` ${C.yellow}Enter Trello API Key: ${C.reset}`)).trim();
|
|
1823
|
+
|
|
1824
|
+
if (apiKey) {
|
|
1825
|
+
const tokenUrl = `https://trello.com/1/authorize?expiration=never&scope=read,write&response_type=token&key=${apiKey}&name=AWKit`;
|
|
1826
|
+
log('');
|
|
1827
|
+
log(` ${C.cyan}👉 Open this link to generate your Token:${C.reset}`);
|
|
1828
|
+
log(` ${C.green}${tokenUrl}${C.reset}`);
|
|
1829
|
+
log('');
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
const apiToken = (await question(` ${C.yellow}Enter Trello API Token: ${C.reset}`)).trim();
|
|
1833
|
+
|
|
1834
|
+
if (apiKey && apiToken) {
|
|
1835
|
+
let profilePath = path.join(os.homedir(), '.zshrc');
|
|
1836
|
+
if (!fs.existsSync(profilePath) && fs.existsSync(path.join(os.homedir(), '.bashrc'))) {
|
|
1837
|
+
profilePath = path.join(os.homedir(), '.bashrc');
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
const exportLines = `\n# Trello API Credentials for AWKit\nexport TRELLO_KEY="${apiKey}"\nexport TRELLO_TOKEN="${apiToken}"\n`;
|
|
1841
|
+
fs.appendFileSync(profilePath, exportLines);
|
|
1842
|
+
|
|
1843
|
+
ok(`Credentials saved to ${profilePath}`);
|
|
1844
|
+
log(` ${C.cyan}👉 Please run 'source ~/${path.basename(profilePath)}' or restart your terminal to apply them.${C.reset}`);
|
|
1845
|
+
} else {
|
|
1846
|
+
warn('Setup skipped. Automated Trello sync will be disabled.');
|
|
1847
|
+
}
|
|
1848
|
+
} catch (e) {
|
|
1849
|
+
warn('Failed to setup Trello interactively.');
|
|
1850
|
+
} finally {
|
|
1851
|
+
rl.close();
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1776
1855
|
// ── 4. CODEBASE.md ────────────────────────────────────────────────────────
|
|
1777
1856
|
const codebasePath = path.join(cwd, 'CODEBASE.md');
|
|
1778
1857
|
if (fs.existsSync(codebasePath) && !forceFlag) {
|
|
@@ -1808,7 +1887,7 @@ function cmdInit(forceFlag = false) {
|
|
|
1808
1887
|
log('');
|
|
1809
1888
|
dim(`Type: ${projectType}`);
|
|
1810
1889
|
dim(`Firebase: analytics, crashlytics, remote-config, auth`);
|
|
1811
|
-
dim(`Files: .project-identity, ${workspaceName}, CODEBASE.md`);
|
|
1890
|
+
dim(`Files: .project-identity, ${workspaceName}, CODEBASE.md, .trello-config.json`);
|
|
1812
1891
|
dim(`Symphony: task tracking ready)`);
|
|
1813
1892
|
log('');
|
|
1814
1893
|
log(`${C.cyan}👉 Open ${workspaceName} in VS Code to get started.${C.reset}`);
|
|
@@ -2011,6 +2090,163 @@ function cmdTelegram(args) {
|
|
|
2011
2090
|
}
|
|
2012
2091
|
}
|
|
2013
2092
|
|
|
2093
|
+
// ─── Trello Integration ───────────────────────────────────────────────────────
|
|
2094
|
+
|
|
2095
|
+
/**
|
|
2096
|
+
* Load Trello credentials from environment variables.
|
|
2097
|
+
* Returns { api_key, api_token } or null.
|
|
2098
|
+
*/
|
|
2099
|
+
function trelloLoadCredentials() {
|
|
2100
|
+
if (process.env.TRELLO_KEY && process.env.TRELLO_TOKEN) {
|
|
2101
|
+
return { api_key: process.env.TRELLO_KEY, api_token: process.env.TRELLO_TOKEN };
|
|
2102
|
+
}
|
|
2103
|
+
return null;
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
/**
|
|
2107
|
+
* Load Trello project config from .trello-config.json in CWD.
|
|
2108
|
+
* Returns { board, list, card } or null.
|
|
2109
|
+
*/
|
|
2110
|
+
function trelloLoadProjectConfig() {
|
|
2111
|
+
const configPath = path.join(process.cwd(), '.trello-config.json');
|
|
2112
|
+
if (!fs.existsSync(configPath)) return null;
|
|
2113
|
+
try {
|
|
2114
|
+
const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
2115
|
+
return {
|
|
2116
|
+
board: cfg.BOARD_NAME || cfg.board,
|
|
2117
|
+
list: cfg.LIST_NAME || cfg.list,
|
|
2118
|
+
card: cfg.CARD_NAME || cfg.card,
|
|
2119
|
+
};
|
|
2120
|
+
} catch (_) {
|
|
2121
|
+
return null;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
/**
|
|
2126
|
+
* Execute a trello-cli command with auto-injected credentials and rate-limit retries.
|
|
2127
|
+
*/
|
|
2128
|
+
function trelloExec(cliArgs, retries = 3) {
|
|
2129
|
+
const cred = trelloLoadCredentials();
|
|
2130
|
+
const cfg = trelloLoadProjectConfig();
|
|
2131
|
+
if (!cred) {
|
|
2132
|
+
err('Trello credentials not found.');
|
|
2133
|
+
log(` Please export ${C.cyan}TRELLO_KEY${C.reset} and ${C.cyan}TRELLO_TOKEN${C.reset} in your ~/.zshrc`);
|
|
2134
|
+
return false;
|
|
2135
|
+
}
|
|
2136
|
+
if (!cfg) {
|
|
2137
|
+
err('.trello-config.json not found in current directory.');
|
|
2138
|
+
log(` Run ${C.cyan}awkit init${C.reset} to generate one, or create it manually.`);
|
|
2139
|
+
return false;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
const env = { ...process.env, TRELLO_KEY: cred.api_key, TRELLO_TOKEN: cred.api_token };
|
|
2143
|
+
const fullArgs = [...cliArgs, '--board', cfg.board, '--list', cfg.list, '--card', cfg.card];
|
|
2144
|
+
|
|
2145
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
2146
|
+
const result = spawnSync('npx', ['--yes', 'trello-cli', ...fullArgs], {
|
|
2147
|
+
env,
|
|
2148
|
+
encoding: 'utf-8',
|
|
2149
|
+
timeout: 30000,
|
|
2150
|
+
});
|
|
2151
|
+
|
|
2152
|
+
const stdoutStr = result.stdout || '';
|
|
2153
|
+
const stderrStr = result.stderr || '';
|
|
2154
|
+
const combinedOut = stdoutStr + stderrStr;
|
|
2155
|
+
|
|
2156
|
+
if (stdoutStr) process.stdout.write(stdoutStr);
|
|
2157
|
+
if (stderrStr) process.stderr.write(stderrStr);
|
|
2158
|
+
|
|
2159
|
+
if (result.status === 0) {
|
|
2160
|
+
return true;
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
if (combinedOut.includes('429') || combinedOut.includes('Rate limit exceeded') || combinedOut.includes('Too Many Requests') || combinedOut.includes('API_TOKEN_LIMIT_EXCEEDED') || combinedOut.includes('API_KEY_LIMIT_EXCEEDED')) {
|
|
2164
|
+
warn(`[Trello API] Rate limit hit (429). Waiting 10s before retry ${attempt}/${retries}...`);
|
|
2165
|
+
// Sleep for 10 seconds to satisfy the 100 requests / 10s window boundary
|
|
2166
|
+
spawnSync('sleep', ['10']);
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
warn(`Trello CLI returned non-zero exit code (${result.status}). Command: awkit trello ${cliArgs.join(' ')}`);
|
|
2171
|
+
return false;
|
|
2172
|
+
}
|
|
2173
|
+
err('Trello CLI failed after multiple retries due to rate limits.');
|
|
2174
|
+
return false;
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
function trelloHelp() {
|
|
2178
|
+
log('');
|
|
2179
|
+
log(`${C.cyan}${C.bold}📋 Trello Commands${C.reset}`);
|
|
2180
|
+
log('');
|
|
2181
|
+
log(` ${C.green}awkit trello desc${C.reset} <text> Update card description`);
|
|
2182
|
+
log(` ${C.green}awkit trello comment${C.reset} <text> Add milestone comment to card`);
|
|
2183
|
+
log(` ${C.green}awkit trello item${C.reset} <name> Add checklist item (incomplete)`);
|
|
2184
|
+
log(` ${C.green}awkit trello complete${C.reset} <name> Mark checklist item ✅ complete`);
|
|
2185
|
+
log(` ${C.green}awkit trello block${C.reset} <reason> Label card Blocked + comment`);
|
|
2186
|
+
log(` ${C.green}awkit trello checklist${C.reset} <name> Create a new checklist on card`);
|
|
2187
|
+
log('');
|
|
2188
|
+
log(` ${C.gray}Credentials: env vars TRELLO_KEY and TRELLO_TOKEN${C.reset}`);
|
|
2189
|
+
log(` ${C.gray}Project config: .trello-config.json in CWD${C.reset}`);
|
|
2190
|
+
log('');
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
function cmdTrello(args) {
|
|
2194
|
+
const subCmd = args[0];
|
|
2195
|
+
const text = args.slice(1).join(' ');
|
|
2196
|
+
|
|
2197
|
+
if (!subCmd || subCmd === 'help') {
|
|
2198
|
+
trelloHelp();
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
if (!text && subCmd !== 'help') {
|
|
2203
|
+
err(`Missing argument for 'trello ${subCmd}'. Usage: awkit trello ${subCmd} <text>`);
|
|
2204
|
+
return;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
switch (subCmd) {
|
|
2208
|
+
case 'desc':
|
|
2209
|
+
info(`Updating card description...`);
|
|
2210
|
+
trelloExec(['card:update', '--desc', text]);
|
|
2211
|
+
break;
|
|
2212
|
+
|
|
2213
|
+
case 'comment':
|
|
2214
|
+
info(`Adding comment to card...`);
|
|
2215
|
+
trelloExec(['card:comment', '--text', text]);
|
|
2216
|
+
break;
|
|
2217
|
+
|
|
2218
|
+
case 'item':
|
|
2219
|
+
// trello-cli doesn't support adding checklist items natively.
|
|
2220
|
+
// We fall back to marking an item incomplete (which implicitly creates it in some versions)
|
|
2221
|
+
// or inform the user to use the REST API.
|
|
2222
|
+
info(`Adding checklist item: ${text}`);
|
|
2223
|
+
warn('Note: trello-cli may not support adding items. Use REST API if this fails.');
|
|
2224
|
+
trelloExec(['card:check-item', '--item', text, '--state', 'incomplete']);
|
|
2225
|
+
break;
|
|
2226
|
+
|
|
2227
|
+
case 'complete':
|
|
2228
|
+
info(`Marking item complete: ${text}`);
|
|
2229
|
+
trelloExec(['card:check-item', '--item', text, '--state', 'complete']);
|
|
2230
|
+
break;
|
|
2231
|
+
|
|
2232
|
+
case 'block':
|
|
2233
|
+
info(`Blocking card with reason...`);
|
|
2234
|
+
trelloExec(['card:label', '--label', 'Blocked']);
|
|
2235
|
+
trelloExec(['card:comment', '--text', `⚠️ BLOCKED: ${text}`]);
|
|
2236
|
+
break;
|
|
2237
|
+
|
|
2238
|
+
case 'checklist':
|
|
2239
|
+
info(`Creating checklist: ${text}`);
|
|
2240
|
+
trelloExec(['card:checklist', '-n', text]);
|
|
2241
|
+
break;
|
|
2242
|
+
|
|
2243
|
+
default:
|
|
2244
|
+
err(`Unknown trello subcommand: ${subCmd}`);
|
|
2245
|
+
trelloHelp();
|
|
2246
|
+
break;
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2014
2250
|
// ─── Auto-Update Checker ──────────────────────────────────────────────────────
|
|
2015
2251
|
|
|
2016
2252
|
function checkAutoUpdate() {
|
|
@@ -2056,66 +2292,71 @@ checkAutoUpdate();
|
|
|
2056
2292
|
|
|
2057
2293
|
const [, , command, ...args] = process.argv;
|
|
2058
2294
|
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2295
|
+
(async () => {
|
|
2296
|
+
switch (command) {
|
|
2297
|
+
case 'init':
|
|
2298
|
+
await cmdInit(args.includes('--force'));
|
|
2299
|
+
break;
|
|
2300
|
+
case 'install':
|
|
2301
|
+
// Parse platform from either first arg or --platform flag
|
|
2302
|
+
{
|
|
2303
|
+
const pIdx = args.indexOf('--platform');
|
|
2304
|
+
let platformArg = null;
|
|
2305
|
+
if (pIdx !== -1 && args[pIdx + 1]) {
|
|
2306
|
+
platformArg = args[pIdx + 1];
|
|
2307
|
+
} else if (args[0] && !args[0].startsWith('-')) {
|
|
2308
|
+
platformArg = args[0];
|
|
2309
|
+
}
|
|
2310
|
+
cmdInstall(platformArg);
|
|
2072
2311
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2312
|
+
break;
|
|
2313
|
+
case 'uninstall':
|
|
2314
|
+
cmdUninstall();
|
|
2315
|
+
break;
|
|
2316
|
+
case 'update':
|
|
2317
|
+
cmdUpdate();
|
|
2318
|
+
break;
|
|
2319
|
+
case 'sync':
|
|
2320
|
+
cmdSync();
|
|
2321
|
+
break;
|
|
2322
|
+
case 'status':
|
|
2323
|
+
cmdStatus();
|
|
2324
|
+
break;
|
|
2325
|
+
case 'harvest':
|
|
2326
|
+
cmdHarvest(args.includes('--dry-run'));
|
|
2327
|
+
break;
|
|
2328
|
+
case 'doctor':
|
|
2329
|
+
cmdDoctor();
|
|
2330
|
+
break;
|
|
2331
|
+
case 'enable-pack':
|
|
2332
|
+
cmdEnablePack(args[0]);
|
|
2333
|
+
break;
|
|
2334
|
+
case 'disable-pack':
|
|
2335
|
+
cmdDisablePack(args[0]);
|
|
2336
|
+
break;
|
|
2337
|
+
case 'list-packs':
|
|
2338
|
+
cmdListPacks();
|
|
2339
|
+
break;
|
|
2340
|
+
case 'version':
|
|
2341
|
+
case '--version':
|
|
2342
|
+
case '-v':
|
|
2343
|
+
cmdVersion();
|
|
2344
|
+
break;
|
|
2345
|
+
case 'lint':
|
|
2346
|
+
cmdLint();
|
|
2347
|
+
break;
|
|
2348
|
+
case 'trello':
|
|
2349
|
+
cmdTrello(args);
|
|
2350
|
+
break;
|
|
2351
|
+
case 'tg':
|
|
2352
|
+
case 'telegram':
|
|
2353
|
+
cmdTelegram(args);
|
|
2354
|
+
break;
|
|
2355
|
+
case 'help':
|
|
2356
|
+
case '--help':
|
|
2357
|
+
case '-h':
|
|
2358
|
+
default:
|
|
2359
|
+
cmdHelp();
|
|
2360
|
+
break;
|
|
2361
|
+
}
|
|
2362
|
+
})();
|
package/core/GEMINI.md
CHANGED
|
@@ -50,19 +50,22 @@ Mỗi skill tự xử lý gate logic riêng — xem SKILL.md của từng skill.
|
|
|
50
50
|
- AI models: Gemini 2.5+ only.
|
|
51
51
|
- Firebase: Firebase AI Logic SDK.
|
|
52
52
|
|
|
53
|
-
###
|
|
53
|
+
### 6-Gate Autonomous System (v12.1)
|
|
54
54
|
- orchestrator PHẢI triage complexity (TRIVIAL/MODERATE/COMPLEX) trước mọi task.
|
|
55
|
-
- COMPLEX tasks PHẢI qua
|
|
55
|
+
- COMPLEX tasks PHẢI qua 6 Gates tuần tự:
|
|
56
56
|
- Gate 1 (Spec): `brainstorm-agent` → BRIEF.md / spec document
|
|
57
|
+
- Gate 1.5 (Module Spec): `module-spec-writer` → per-module product specs (screens, flows, rules)
|
|
57
58
|
- Gate 2 (Architecture): `spec-gate` → design doc + user approve
|
|
58
59
|
- Gate 3 (Tasks): `symphony-enforcer` → tạo Symphony tickets
|
|
59
60
|
- Gate 4 (Execution): code theo ticket, đối chiếu design doc
|
|
60
61
|
- Gate 5 (Verification): `verification-gate` + `code-review`
|
|
62
|
+
- Gate 1.5 MANDATORY khi: COMPLEX + >3 modules hoặc port/migration projects.
|
|
63
|
+
- Gate 1.5 SKIP khi: TRIVIAL/MODERATE hoặc single-module projects.
|
|
61
64
|
- TRIVIAL tasks bypass → thẳng Gate 4.
|
|
62
65
|
- MODERATE tasks → Gate 3 + 4 + 5.
|
|
63
66
|
- AI tự detect gate state — user KHÔNG CẦN gọi workflow bằng tay.
|
|
64
67
|
- Trong lúc code, nếu cần sửa schema khác approved design → ⛔ DỪNG, quay Gate 2.
|
|
65
|
-
- Chi tiết: xem `orchestrator/SKILL.md` (triage) + `spec-gate/SKILL.md` (Gate 2).
|
|
68
|
+
- Chi tiết: xem `orchestrator/SKILL.md` (triage) + `module-spec-writer/SKILL.md` (Gate 1.5) + `spec-gate/SKILL.md` (Gate 2).
|
|
66
69
|
|
|
67
70
|
### NeuralMemory
|
|
68
71
|
- Brain = projectId. Switch trước mọi nmem call.
|
|
@@ -109,6 +112,16 @@ Khi AI cần tự quyết định mà không hỏi user:
|
|
|
109
112
|
- KHÔNG hỏi user về project structure.
|
|
110
113
|
- CODEBASE.md outdated → ghi chú "⚠️ dùng /codebase-sync".
|
|
111
114
|
|
|
115
|
+
### GitNexus (Code Intelligence)
|
|
116
|
+
- Project đã index (`.gitnexus/` tồn tại) → PHẢI dùng GitNexus tools.
|
|
117
|
+
- Trước khi edit symbol → `gitnexus_impact` check blast radius.
|
|
118
|
+
- Trước khi commit → `gitnexus_detect_changes()` verify scope.
|
|
119
|
+
- Risk HIGH/CRITICAL → PHẢI cảnh báo user trước khi sửa.
|
|
120
|
+
- Explore code lạ → ưu tiên `gitnexus_query` thay vì grep thủ công.
|
|
121
|
+
- Rename symbol → PHẢI dùng `gitnexus_rename` (dry_run trước).
|
|
122
|
+
- Index stale → cảnh báo "⚠️ chạy `npx gitnexus analyze`".
|
|
123
|
+
- Chi tiết: xem `gitnexus-intelligence/SKILL.md`.
|
|
124
|
+
|
|
112
125
|
### Two-Agent Flow (Conductor)
|
|
113
126
|
- Antigravity CHỦ ĐỘNG gọi `gemini -p "..." --approval-mode plan` khi cần tầm nhìn rộng.
|
|
114
127
|
- CLI dùng **quota pool riêng** → không ảnh hưởng Antigravity quota.
|
|
@@ -123,9 +136,10 @@ Khi AI cần tự quyết định mà không hỏi user:
|
|
|
123
136
|
## Routing
|
|
124
137
|
|
|
125
138
|
- **Execution order:** `symphony-orchestrator` → `awf-session-restore` → `nm-memory-sync` → `symphony-enforcer` → `orchestrator` (triage + gate-check) → action
|
|
126
|
-
- **Gate skills:** `orchestrator` (triage) → `brainstorm-agent` (G1) → `spec-gate` (G2) → `symphony-enforcer` (G3) → `verification-gate` (G5)
|
|
139
|
+
- **Gate skills:** `orchestrator` (triage) → `brainstorm-agent` (G1) → `module-spec-writer` (G1.5) → `spec-gate` (G2) → `symphony-enforcer` (G3) → `verification-gate` (G5)
|
|
140
|
+
- **Code intelligence:** `gitnexus-intelligence` (impact analysis, blast radius, safe refactoring)
|
|
127
141
|
- **Skill catalog:** xem `orchestrator/SKILL.md`
|
|
128
|
-
- **Workflows:** 75+ (`/xxx`). Core: `/init` `/code` `/debug` `/recap` `/next` `/todo`
|
|
142
|
+
- **Workflows:** 75+ (`/xxx`). Core: `/init` `/code` `/debug` `/recap` `/next` `/todo` `/gitnexus`
|
|
129
143
|
- **Shortcuts:** `/todo` `/done` `/next`
|
|
130
144
|
|
|
131
145
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leejungkiin/awkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Antigravity Workflow Kit. Unified AI agent orchestration system.",
|
|
5
5
|
"main": "bin/awk.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,10 @@
|
|
|
34
34
|
"templates/",
|
|
35
35
|
"docs/",
|
|
36
36
|
"README.md",
|
|
37
|
-
"CHANGELOG.md"
|
|
38
|
-
"VERSION"
|
|
37
|
+
"CHANGELOG.md"
|
|
39
38
|
],
|
|
40
39
|
"dependencies": {
|
|
41
40
|
"@leejungkiin/awkit-symphony": "^0.1.0",
|
|
42
41
|
"@leejungkiin/gitnexus": "file:../gitnexus/gitnexus"
|
|
43
42
|
}
|
|
44
|
-
}
|
|
43
|
+
}
|
package/skills/CATALOG.md
CHANGED
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
| 11 | `awf-context-help` | `auto` | `/help`, stuck | — | — | ✅ Active |
|
|
32
32
|
| 12 | `auto-save` | `auto` | Session end | — | — | ✅ Background |
|
|
33
33
|
| 13 | `awf-version-tracker` | `auto` | Skill changes | — | — | ✅ Background |
|
|
34
|
+
| 14 | `module-spec-writer` | `auto` | Gate 1.5 check fail | 1.5 | 1.0.0 | ✅ Active |
|
|
35
|
+
| 15 | `spec-gate` | `auto` | Gate 2 check fail | 2 | 1.0.0 | ✅ Active |
|
|
36
|
+
| 16 | `visual-design-gate` | `auto` | Gate 2.5 check fail | 2.5 | 1.0.0 | ✅ Active |
|
|
37
|
+
| 17 | `trello-sync` | `auto` | Always | 2 | 3.0.0 | ✅ Active |
|
|
34
38
|
|
|
35
39
|
---
|
|
36
40
|
|