specweave 1.0.288 → 1.0.290
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/specweave.js +1 -33
- package/dist/dashboard/assets/index-BGpS5omm.css +1 -0
- package/dist/dashboard/assets/index-BvNL0nTV.js +11 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.js +12 -0
- package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
- package/dist/src/cli/commands/update.d.ts.map +1 -1
- package/dist/src/cli/commands/update.js +13 -0
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/helpers/init/plugin-installer.js +20 -0
- package/dist/src/cli/helpers/init/plugin-installer.js.map +1 -1
- package/dist/src/cli/workers/marketplace-scanner-worker.d.ts.map +1 -1
- package/dist/src/cli/workers/marketplace-scanner-worker.js +42 -7
- package/dist/src/cli/workers/marketplace-scanner-worker.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/fabric/discovery/content-fetcher.d.ts +15 -0
- package/dist/src/core/fabric/discovery/content-fetcher.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/content-fetcher.js +32 -0
- package/dist/src/core/fabric/discovery/content-fetcher.js.map +1 -0
- package/dist/src/core/fabric/discovery/github-provider.d.ts +22 -0
- package/dist/src/core/fabric/discovery/github-provider.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/github-provider.js +61 -0
- package/dist/src/core/fabric/discovery/github-provider.js.map +1 -0
- package/dist/src/core/fabric/discovery/npm-provider.d.ts +13 -0
- package/dist/src/core/fabric/discovery/npm-provider.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/npm-provider.js +57 -0
- package/dist/src/core/fabric/discovery/npm-provider.js.map +1 -0
- package/dist/src/core/fabric/discovery/scan-pipeline.d.ts +23 -0
- package/dist/src/core/fabric/discovery/scan-pipeline.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/scan-pipeline.js +67 -0
- package/dist/src/core/fabric/discovery/scan-pipeline.js.map +1 -0
- package/dist/src/core/fabric/discovery/skillssh-provider.d.ts +13 -0
- package/dist/src/core/fabric/discovery/skillssh-provider.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/skillssh-provider.js +47 -0
- package/dist/src/core/fabric/discovery/skillssh-provider.js.map +1 -0
- package/dist/src/core/fabric/discovery/source-registry.d.ts +21 -0
- package/dist/src/core/fabric/discovery/source-registry.d.ts.map +1 -0
- package/dist/src/core/fabric/discovery/source-registry.js +38 -0
- package/dist/src/core/fabric/discovery/source-registry.js.map +1 -0
- package/dist/src/core/fabric/security-judge.d.ts +2 -0
- package/dist/src/core/fabric/security-judge.d.ts.map +1 -1
- package/dist/src/core/fabric/security-judge.js +48 -0
- package/dist/src/core/fabric/security-judge.js.map +1 -1
- package/dist/src/core/fabric/submission-queue-types.d.ts +1 -0
- package/dist/src/core/fabric/submission-queue-types.d.ts.map +1 -1
- package/dist/src/core/fabric/submission-queue.d.ts +5 -0
- package/dist/src/core/fabric/submission-queue.d.ts.map +1 -1
- package/dist/src/core/fabric/submission-queue.js +13 -0
- package/dist/src/core/fabric/submission-queue.js.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.js +3 -2
- package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
- package/dist/src/core/llm/budget-guard.d.ts +56 -0
- package/dist/src/core/llm/budget-guard.d.ts.map +1 -0
- package/dist/src/core/llm/budget-guard.js +165 -0
- package/dist/src/core/llm/budget-guard.js.map +1 -0
- package/dist/src/core/llm/fallback-provider.d.ts +32 -0
- package/dist/src/core/llm/fallback-provider.d.ts.map +1 -0
- package/dist/src/core/llm/fallback-provider.js +53 -0
- package/dist/src/core/llm/fallback-provider.js.map +1 -0
- package/dist/src/core/llm/index.d.ts +5 -0
- package/dist/src/core/llm/index.d.ts.map +1 -1
- package/dist/src/core/llm/index.js +5 -0
- package/dist/src/core/llm/index.js.map +1 -1
- package/dist/src/core/llm/provider-factory.d.ts.map +1 -1
- package/dist/src/core/llm/provider-factory.js +31 -0
- package/dist/src/core/llm/provider-factory.js.map +1 -1
- package/dist/src/core/llm/providers/workers-ai-provider.d.ts +45 -0
- package/dist/src/core/llm/providers/workers-ai-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/workers-ai-provider.js +140 -0
- package/dist/src/core/llm/providers/workers-ai-provider.js.map +1 -0
- package/dist/src/core/llm/types.d.ts +21 -1
- package/dist/src/core/llm/types.d.ts.map +1 -1
- package/dist/src/core/llm/types.js +7 -0
- package/dist/src/core/llm/types.js.map +1 -1
- package/dist/src/core/notifications/notification-types.d.ts +1 -1
- package/dist/src/core/notifications/notification-types.d.ts.map +1 -1
- package/dist/src/core/notifications/notification-types.js +2 -0
- package/dist/src/core/notifications/notification-types.js.map +1 -1
- package/dist/src/core/plugins/plugin-loader.d.ts +0 -7
- package/dist/src/core/plugins/plugin-loader.d.ts.map +1 -1
- package/dist/src/core/plugins/plugin-loader.js +0 -21
- package/dist/src/core/plugins/plugin-loader.js.map +1 -1
- package/dist/src/core/plugins/skill-trigger-extractor.d.ts.map +1 -1
- package/dist/src/core/plugins/skill-trigger-extractor.js +6 -0
- package/dist/src/core/plugins/skill-trigger-extractor.js.map +1 -1
- package/dist/src/core/types/plugin.d.ts +0 -5
- package/dist/src/core/types/plugin.d.ts.map +1 -1
- package/dist/src/core/types/plugin.js.map +1 -1
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/utils/claude-plugin-cli.d.ts +32 -0
- package/dist/src/utils/claude-plugin-cli.d.ts.map +1 -0
- package/dist/src/utils/claude-plugin-cli.js +71 -0
- package/dist/src/utils/claude-plugin-cli.js.map +1 -0
- package/dist/src/utils/plugin-copier.d.ts +5 -0
- package/dist/src/utils/plugin-copier.d.ts.map +1 -1
- package/dist/src/utils/plugin-copier.js +24 -1
- package/dist/src/utils/plugin-copier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/user-prompt-submit.sh +34 -1
- package/plugins/specweave/skills/npm/SKILL.md +1 -0
- package/plugins/specweave-jira/skills/jira-mapper/SKILL.md +77 -7
- package/plugins/specweave-jira/skills/jira-sync/SKILL.md +21 -71
- package/dist/dashboard/assets/index-Cs3Zq6E2.css +0 -1
- package/dist/dashboard/assets/index-DQ_KfIRg.js +0 -11
- package/dist/src/cli/commands/context.d.ts +0 -92
- package/dist/src/cli/commands/context.d.ts.map +0 -1
- package/dist/src/cli/commands/context.js +0 -205
- package/dist/src/cli/commands/context.js.map +0 -1
|
@@ -108,11 +108,6 @@ export interface Skill {
|
|
|
108
108
|
description: string;
|
|
109
109
|
/** Test cases for this skill */
|
|
110
110
|
testCases?: TestCase[];
|
|
111
|
-
/**
|
|
112
|
-
* Visibility level (v1.0.102+)
|
|
113
|
-
* @default "public"
|
|
114
|
-
*/
|
|
115
|
-
visibility?: 'public' | 'internal';
|
|
116
111
|
}
|
|
117
112
|
/**
|
|
118
113
|
* Agent - Specialized role with isolated context
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/types/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IAEb,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IAEpB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAEhB,yCAAyC;IACzC,MAAM,EAAE;QACN,kBAAkB;QAClB,IAAI,EAAE,MAAM,CAAC;QAEb,8BAA8B;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf,4BAA4B;QAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IAEF,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,UAAU,CAAC,EAAE;QACX,oCAAoC;QACpC,IAAI,EAAE,MAAM,CAAC;QAEb,qBAAqB;QACrB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IAEF,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,yEAAyE;IACzE,YAAY,CAAC,EAAE;QACb,oCAAoC;QACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IAEF,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4DAA4D;IAC5D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC,sFAAsF;IACtF,QAAQ,CAAC,EAAE;QACT,0BAA0B;QAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,0BAA0B;QAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,4BAA4B;QAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,yBAAyB;QACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IAEF,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,iDAAiD;IACjD,WAAW,CAAC,EAAE;QACZ,oDAAoD;QACpD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,yCAAyC;QACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,oDAAoD;QACpD,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QACf,0BAA0B;QAC1B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,gDAAgD;QAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,kCAAkC;QAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IAEF,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,wDAAwD;IACxD,OAAO,CAAC,EAAE;QACR,4CAA4C;QAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,6BAA6B;QAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,mBAAmB;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,6CAA6C;QAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,kCAAkC;QAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IAEb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IAEb,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IAEpB,gCAAgC;IAChC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../src/core/types/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/core/types/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/core/types/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyTH;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YACE,OAAe,EACR,UAAmB,EACnB,IAAa;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,eAAU,GAAV,UAAU,CAAS;QACnB,SAAI,GAAJ,IAAI,CAAS;QAGpB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,uBAAwB,SAAQ,WAAW;IACtD,YAAY,OAAe,EAAE,UAAmB;QAC9C,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,WAAW;IAClD,YAAY,UAAkB;QAC5B,KAAK,CAAC,WAAW,UAAU,aAAa,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,WAAW;IACpD,YAAY,OAAe,EAAE,UAAmB;QAC9C,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -73,12 +73,12 @@ export declare const VisionInsightsSchema: z.ZodObject<{
|
|
|
73
73
|
education: "education";
|
|
74
74
|
iot: "iot";
|
|
75
75
|
gaming: "gaming";
|
|
76
|
+
marketplace: "marketplace";
|
|
76
77
|
"productivity-saas": "productivity-saas";
|
|
77
78
|
"e-commerce": "e-commerce";
|
|
78
79
|
"social-network": "social-network";
|
|
79
80
|
"enterprise-b2b": "enterprise-b2b";
|
|
80
81
|
"consumer-b2c": "consumer-b2c";
|
|
81
|
-
marketplace: "marketplace";
|
|
82
82
|
blockchain: "blockchain";
|
|
83
83
|
"ai-ml": "ai-ml";
|
|
84
84
|
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Plugin CLI Integration
|
|
3
|
+
*
|
|
4
|
+
* Registers SpecWeave plugins with Claude Code's plugin system via the
|
|
5
|
+
* `claude` CLI binary. This makes plugins appear in the `/plugin Installed`
|
|
6
|
+
* UI alongside marketplace metadata.
|
|
7
|
+
*
|
|
8
|
+
* All operations are non-fatal — failures are logged (in DEBUG mode) but
|
|
9
|
+
* never block the primary plugin installation to ~/.claude/commands/.
|
|
10
|
+
*
|
|
11
|
+
* @since 1.0.290
|
|
12
|
+
*/
|
|
13
|
+
export interface CliRegistrationResult {
|
|
14
|
+
/** True if marketplace was registered successfully */
|
|
15
|
+
marketplaceRegistered: boolean;
|
|
16
|
+
/** Plugin names that were successfully installed via CLI */
|
|
17
|
+
installedPlugins: string[];
|
|
18
|
+
/** Plugin names that failed CLI installation */
|
|
19
|
+
failedPlugins: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Register SpecWeave marketplace and install plugins via Claude CLI.
|
|
23
|
+
*
|
|
24
|
+
* Steps:
|
|
25
|
+
* 1. Validates specweaveRoot contains .claude-plugin/marketplace.json
|
|
26
|
+
* 2. Runs `claude plugin marketplace add <specweaveRoot>`
|
|
27
|
+
* 3. Runs `claude plugin install <name>@specweave` for each plugin
|
|
28
|
+
*
|
|
29
|
+
* Entirely non-fatal. Returns a result with success/failure per plugin.
|
|
30
|
+
*/
|
|
31
|
+
export declare function registerPluginsWithClaudeCli(specweaveRoot: string, pluginNames: string[]): CliRegistrationResult;
|
|
32
|
+
//# sourceMappingURL=claude-plugin-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-plugin-cli.d.ts","sourceRoot":"","sources":["../../../src/utils/claude-plugin-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gDAAgD;IAChD,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EAAE,GACpB,qBAAqB,CA2CvB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Plugin CLI Integration
|
|
3
|
+
*
|
|
4
|
+
* Registers SpecWeave plugins with Claude Code's plugin system via the
|
|
5
|
+
* `claude` CLI binary. This makes plugins appear in the `/plugin Installed`
|
|
6
|
+
* UI alongside marketplace metadata.
|
|
7
|
+
*
|
|
8
|
+
* All operations are non-fatal — failures are logged (in DEBUG mode) but
|
|
9
|
+
* never block the primary plugin installation to ~/.claude/commands/.
|
|
10
|
+
*
|
|
11
|
+
* @since 1.0.290
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { execFileNoThrowSync } from './execFileNoThrow.js';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Core
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Register SpecWeave marketplace and install plugins via Claude CLI.
|
|
21
|
+
*
|
|
22
|
+
* Steps:
|
|
23
|
+
* 1. Validates specweaveRoot contains .claude-plugin/marketplace.json
|
|
24
|
+
* 2. Runs `claude plugin marketplace add <specweaveRoot>`
|
|
25
|
+
* 3. Runs `claude plugin install <name>@specweave` for each plugin
|
|
26
|
+
*
|
|
27
|
+
* Entirely non-fatal. Returns a result with success/failure per plugin.
|
|
28
|
+
*/
|
|
29
|
+
export function registerPluginsWithClaudeCli(specweaveRoot, pluginNames) {
|
|
30
|
+
const result = {
|
|
31
|
+
marketplaceRegistered: false,
|
|
32
|
+
installedPlugins: [],
|
|
33
|
+
failedPlugins: [],
|
|
34
|
+
};
|
|
35
|
+
if (pluginNames.length === 0)
|
|
36
|
+
return result;
|
|
37
|
+
// Validate marketplace exists at path
|
|
38
|
+
const marketplacePath = join(specweaveRoot, '.claude-plugin', 'marketplace.json');
|
|
39
|
+
if (!existsSync(marketplacePath)) {
|
|
40
|
+
if (process.env.DEBUG) {
|
|
41
|
+
console.warn(`[DEBUG] Skipping Claude CLI registration: no marketplace.json at ${marketplacePath}`);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
// Register marketplace
|
|
46
|
+
const addResult = execFileNoThrowSync('claude', ['plugin', 'marketplace', 'add', specweaveRoot]);
|
|
47
|
+
if (addResult.success || addResult.exitCode === 0) {
|
|
48
|
+
result.marketplaceRegistered = true;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (process.env.DEBUG) {
|
|
52
|
+
console.warn(`[DEBUG] claude plugin marketplace add failed (exit ${addResult.exitCode}): ${addResult.stderr}`);
|
|
53
|
+
}
|
|
54
|
+
// Don't bail — install may still work if marketplace was already registered
|
|
55
|
+
}
|
|
56
|
+
// Install each plugin
|
|
57
|
+
for (const name of pluginNames) {
|
|
58
|
+
const installResult = execFileNoThrowSync('claude', ['plugin', 'install', `${name}@specweave`]);
|
|
59
|
+
if (installResult.success || installResult.exitCode === 0) {
|
|
60
|
+
result.installedPlugins.push(name);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
result.failedPlugins.push(name);
|
|
64
|
+
if (process.env.DEBUG) {
|
|
65
|
+
console.warn(`[DEBUG] claude plugin install ${name}@specweave failed (exit ${installResult.exitCode}): ${installResult.stderr}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=claude-plugin-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-plugin-cli.js","sourceRoot":"","sources":["../../../src/utils/claude-plugin-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAe3D,8EAA8E;AAC9E,OAAO;AACP,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAC1C,aAAqB,EACrB,WAAqB;IAErB,MAAM,MAAM,GAA0B;QACpC,qBAAqB,EAAE,KAAK;QAC5B,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,EAAE;KAClB,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAE5C,sCAAsC;IACtC,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAClF,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,oEAAoE,eAAe,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uBAAuB;IACvB,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;IACjG,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,sDAAsD,SAAS,CAAC,QAAQ,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QACjH,CAAC;QACD,4EAA4E;IAC9E,CAAC;IAED,sBAAsB;IACtB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC;QAChG,IAAI,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1D,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,iCAAiC,IAAI,2BAA2B,aAAa,CAAC,QAAQ,MAAM,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;YACnI,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
* - skills/<name>/anything other than SKILL.md → sub-resources (phases, templates)
|
|
26
26
|
*/
|
|
27
27
|
export declare function shouldSkipFromCommands(relPath: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a SKILL.md file is marked as non-user-invokable via frontmatter.
|
|
30
|
+
* Files with `user-invokable: false` should not be copied to the commands dir.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isNonInvokableSkill(filePath: string): boolean;
|
|
28
33
|
export interface CopyPluginOptions {
|
|
29
34
|
/** Force reinstall even if hash matches lockfile */
|
|
30
35
|
force?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-copier.d.ts","sourceRoot":"","sources":["../../../src/utils/plugin-copier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"plugin-copier.d.ts","sourceRoot":"","sources":["../../../src/utils/plugin-copier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAqBH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA0B/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS7D;AA8BD,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAmBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsB3D;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAW1D;AAuBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ3D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAatD;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsBjE;AAMD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAyDlB"}
|
|
@@ -14,6 +14,7 @@ import { copyFileSync, mkdirSync, chmodSync, readdirSync, statSync, readFileSync
|
|
|
14
14
|
import { join, resolve, dirname } from 'node:path';
|
|
15
15
|
import { createHash } from 'node:crypto';
|
|
16
16
|
import { homedir } from 'node:os';
|
|
17
|
+
import { getProjectRoot } from './find-project-root.js';
|
|
17
18
|
// ---------------------------------------------------------------------------
|
|
18
19
|
// Command file filter
|
|
19
20
|
// ---------------------------------------------------------------------------
|
|
@@ -57,6 +58,22 @@ export function shouldSkipFromCommands(relPath) {
|
|
|
57
58
|
return true;
|
|
58
59
|
return false;
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if a SKILL.md file is marked as non-user-invokable via frontmatter.
|
|
63
|
+
* Files with `user-invokable: false` should not be copied to the commands dir.
|
|
64
|
+
*/
|
|
65
|
+
export function isNonInvokableSkill(filePath) {
|
|
66
|
+
try {
|
|
67
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
68
|
+
const fmMatch = content.match(/^---\n([\s\S]+?)\n---/);
|
|
69
|
+
if (!fmMatch)
|
|
70
|
+
return false;
|
|
71
|
+
return /^user-invokable:\s*false$/m.test(fmMatch[1]);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
60
77
|
/**
|
|
61
78
|
* Recursively copy a plugin directory, skipping files that would pollute
|
|
62
79
|
* the Claude Code commands namespace (see shouldSkipFromCommands).
|
|
@@ -73,6 +90,9 @@ function copyPluginFiltered(sourceDir, targetDir, relBase = '') {
|
|
|
73
90
|
copyPluginFiltered(sourcePath, targetPath, relPath);
|
|
74
91
|
}
|
|
75
92
|
else if (stat.isFile() && !shouldSkipFromCommands(relPath)) {
|
|
93
|
+
// Skip SKILL.md files marked as non-user-invokable (e.g., internal tools)
|
|
94
|
+
if (entry === 'SKILL.md' && isNonInvokableSkill(sourcePath))
|
|
95
|
+
continue;
|
|
76
96
|
copyFileSync(sourcePath, targetPath);
|
|
77
97
|
}
|
|
78
98
|
}
|
|
@@ -103,6 +123,9 @@ export function computePluginHash(pluginDir) {
|
|
|
103
123
|
if (shouldSkipFromCommands(file))
|
|
104
124
|
continue;
|
|
105
125
|
const fullPath = join(pluginDir, file);
|
|
126
|
+
// Skip non-user-invokable SKILL.md files (same as copyPluginFiltered)
|
|
127
|
+
if (file.endsWith('SKILL.md') && isNonInvokableSkill(fullPath))
|
|
128
|
+
continue;
|
|
106
129
|
try {
|
|
107
130
|
hash.update(readFileSync(fullPath, 'utf-8'));
|
|
108
131
|
}
|
|
@@ -249,7 +272,7 @@ export function copyPlugin(pluginName, specweaveRoot, options = {}) {
|
|
|
249
272
|
}
|
|
250
273
|
// 3. Compute hash and check lockfile
|
|
251
274
|
const sha = computePluginHash(sourceDir);
|
|
252
|
-
const lockDir =
|
|
275
|
+
const lockDir = getProjectRoot();
|
|
253
276
|
const lock = ensureLockfile(lockDir);
|
|
254
277
|
if (!options.force && lock.skills[pluginName]?.sha === sha) {
|
|
255
278
|
return { success: true, sha, skipped: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-copier.js","sourceRoot":"","sources":["../../../src/utils/plugin-copier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-copier.js","sourceRoot":"","sources":["../../../src/utils/plugin-copier.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.290",
|
|
4
4
|
"description": "Spec-driven development framework for AI coding agents. First-class support for Claude Code — compatible with any LLM-powered coding tool. Living documentation, autonomous execution, quality gates, and multilingual support (9 languages).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -430,7 +430,9 @@ output_approve_with_context() {
|
|
|
430
430
|
# Returns: 0 if in lockfile, 1 if not
|
|
431
431
|
check_plugin_in_vskill_lock() {
|
|
432
432
|
local plugin="$1"
|
|
433
|
-
|
|
433
|
+
# Use project root if available, else fall back to CWD
|
|
434
|
+
local lock_dir="${SW_PROJECT_ROOT:-$PWD}"
|
|
435
|
+
local lockfile="$lock_dir/vskill.lock"
|
|
434
436
|
|
|
435
437
|
# Check project-local lockfile first
|
|
436
438
|
[[ ! -f "$lockfile" ]] && return 1
|
|
@@ -497,6 +499,37 @@ install_plugin_direct() {
|
|
|
497
499
|
if cp -R "$source_dir/." "$target_dir/" 2>/dev/null; then
|
|
498
500
|
# Fix hook permissions (.sh files need to be executable)
|
|
499
501
|
find "$target_dir" -name "*.sh" -exec chmod 755 {} \; 2>/dev/null || true
|
|
502
|
+
|
|
503
|
+
# Write lockfile entry so subsequent prompts skip re-install
|
|
504
|
+
local lock_dir="${SW_PROJECT_ROOT:-$PWD}"
|
|
505
|
+
local lockfile="$lock_dir/vskill.lock"
|
|
506
|
+
local now
|
|
507
|
+
now=$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -Iseconds 2>/dev/null)
|
|
508
|
+
|
|
509
|
+
if command -v jq >/dev/null 2>&1 && [[ -n "$lock_dir" ]]; then
|
|
510
|
+
local skill_entry
|
|
511
|
+
skill_entry=$(jq -n \
|
|
512
|
+
--arg ver "0.0.0" \
|
|
513
|
+
--arg now "$now" \
|
|
514
|
+
'{version: $ver, sha: "", tier: "BUNDLED", installedAt: $now, source: "local:specweave"}')
|
|
515
|
+
|
|
516
|
+
if [[ -f "$lockfile" ]]; then
|
|
517
|
+
# Merge into existing lockfile
|
|
518
|
+
jq --arg key "$plugin" --argjson entry "$skill_entry" --arg now "$now" \
|
|
519
|
+
'.skills[$key] = $entry | .updatedAt = $now' \
|
|
520
|
+
"$lockfile" > "${lockfile}.tmp" 2>/dev/null && \
|
|
521
|
+
mv "${lockfile}.tmp" "$lockfile" 2>/dev/null || true
|
|
522
|
+
else
|
|
523
|
+
# Create new lockfile
|
|
524
|
+
jq -n \
|
|
525
|
+
--arg now "$now" \
|
|
526
|
+
--arg key "$plugin" \
|
|
527
|
+
--argjson entry "$skill_entry" \
|
|
528
|
+
'{version: 1, agents: ["claude-code"], skills: {($key): $entry}, createdAt: $now, updatedAt: $now}' \
|
|
529
|
+
> "$lockfile" 2>/dev/null || true
|
|
530
|
+
fi
|
|
531
|
+
fi
|
|
532
|
+
|
|
500
533
|
VSKILL_INSTALL_OUTPUT="installed $plugin via direct copy"
|
|
501
534
|
return 0
|
|
502
535
|
else
|
|
@@ -56,6 +56,74 @@ You are an expert in mapping SpecWeave concepts to JIRA and vice versa with prec
|
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|
|
59
|
+
## Security Rules (MANDATORY)
|
|
60
|
+
|
|
61
|
+
These rules apply to ALL JIRA and Confluence API operations in this skill.
|
|
62
|
+
|
|
63
|
+
### Credential Handling
|
|
64
|
+
|
|
65
|
+
1. **Never collect credentials** — this skill reads from `.env` only, never prompts the user
|
|
66
|
+
2. **Never log secrets** — never echo token values, auth headers, or base64 credentials
|
|
67
|
+
3. **Never write credentials** — the user configures `.env` themselves
|
|
68
|
+
|
|
69
|
+
### Credential Loading
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Load credentials from .env (never display values)
|
|
73
|
+
JIRA_API_TOKEN="$(grep '^JIRA_API_TOKEN=' .env | cut -d '=' -f2-)"
|
|
74
|
+
JIRA_EMAIL="$(grep '^JIRA_EMAIL=' .env | cut -d '=' -f2-)"
|
|
75
|
+
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | cut -d '=' -f2-)"
|
|
76
|
+
|
|
77
|
+
# Validate non-empty (without reading into output)
|
|
78
|
+
for KEY in JIRA_API_TOKEN JIRA_EMAIL JIRA_DOMAIN; do
|
|
79
|
+
if ! grep -qE "^${KEY}=.+" .env; then
|
|
80
|
+
echo "Error: ${KEY} missing or empty in .env"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
done
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Domain Validation (before ANY API call)
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Must be a valid hostname — no special chars, no consecutive dots
|
|
90
|
+
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$ ]]; then
|
|
91
|
+
echo "Error: JIRA_DOMAIN contains invalid characters"
|
|
92
|
+
exit 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Cloud JIRA: must match <subdomain>.atlassian.net
|
|
96
|
+
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9-]+\.atlassian\.net$ ]]; then
|
|
97
|
+
echo "Warning: Domain does not match <subdomain>.atlassian.net — requires user confirmation for non-standard domains"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Reject IP addresses (SSRF prevention)
|
|
101
|
+
if [[ "$JIRA_DOMAIN" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]] || [[ "$JIRA_DOMAIN" =~ ^\[.*\]$ ]] || [[ "$JIRA_DOMAIN" =~ ^0x ]]; then
|
|
102
|
+
echo "Error: IP addresses not allowed — use a hostname"
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Reject localhost and private networks
|
|
107
|
+
if [[ "$JIRA_DOMAIN" =~ ^(localhost|127\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.) ]]; then
|
|
108
|
+
echo "Error: Internal/localhost addresses not allowed"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### API Call Pattern (HTTPS only, quoted variables)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
AUTH="$(printf '%s:%s' "$JIRA_EMAIL" "$JIRA_API_TOKEN" | base64)"
|
|
117
|
+
|
|
118
|
+
# All API calls MUST use https://, double-quote all variables
|
|
119
|
+
curl -s -f \
|
|
120
|
+
-H "Authorization: Basic $AUTH" \
|
|
121
|
+
-H "Content-Type: application/json" \
|
|
122
|
+
"https://${JIRA_DOMAIN}/rest/api/3/..."
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
59
127
|
## Conversion Workflows
|
|
60
128
|
|
|
61
129
|
### 1. Export: Increment → JIRA Epic
|
|
@@ -66,7 +134,7 @@ You are an expert in mapping SpecWeave concepts to JIRA and vice versa with prec
|
|
|
66
134
|
- Increment folder exists
|
|
67
135
|
- `spec.md` exists with valid frontmatter
|
|
68
136
|
- `tasks.md` exists
|
|
69
|
-
- JIRA
|
|
137
|
+
- JIRA credentials configured in `.env` (validated per Security Rules above)
|
|
70
138
|
|
|
71
139
|
**Process**:
|
|
72
140
|
|
|
@@ -460,12 +528,14 @@ Sync SpecWeave living docs to Confluence pages. Confluence is commonly paired wi
|
|
|
460
528
|
|
|
461
529
|
### Confluence Credentials
|
|
462
530
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
531
|
+
Same security rules as JIRA credentials (see Security Rules section above). User configures `.env`, skill only validates presence. Same domain validation applies.
|
|
532
|
+
|
|
533
|
+
Required `.env` keys (configured by the user, NOT by this skill):
|
|
534
|
+
```
|
|
535
|
+
CONFLUENCE_API_TOKEN=<your-token> # Same as JIRA API token
|
|
536
|
+
CONFLUENCE_EMAIL=<your-email>
|
|
537
|
+
CONFLUENCE_DOMAIN=<your-company>.atlassian.net
|
|
538
|
+
CONFLUENCE_SPACE_KEY=<space-key>
|
|
469
539
|
```
|
|
470
540
|
|
|
471
541
|
### Page Update Workflow (CRITICAL)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Sync guidance for SpecWeave increments with JIRA epics/stories (content SpecWeave→JIRA, status JIRA→SpecWeave). Use when asking about JIRA integration setup or troubleshooting sync. For actual syncing, use /sw-jira:sync command instead.
|
|
3
|
-
allowed-tools: Read,
|
|
3
|
+
allowed-tools: Read, Task
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# JIRA Sync Skill
|
|
@@ -78,11 +78,11 @@ For self-hosted JIRA: Use a Personal Access Token (PAT) and your server's hostna
|
|
|
78
78
|
### Step 3: Validate Credential Presence (Not Values)
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
|
-
# Validate that required keys exist and
|
|
81
|
+
# Validate that required keys exist and have non-empty values
|
|
82
|
+
# Uses grep -qE to check pattern without reading values into variables
|
|
82
83
|
MISSING=()
|
|
83
84
|
for KEY in JIRA_API_TOKEN JIRA_EMAIL JIRA_DOMAIN; do
|
|
84
|
-
|
|
85
|
-
if [ -z "$VAL" ]; then
|
|
85
|
+
if ! grep -qE "^${KEY}=.+" .env; then
|
|
86
86
|
MISSING+=("$KEY")
|
|
87
87
|
fi
|
|
88
88
|
done
|
|
@@ -97,8 +97,8 @@ echo "All required credentials present"
|
|
|
97
97
|
### Step 4: Domain Validation (Strict)
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
-
# Read domain safely — quote all
|
|
101
|
-
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | cut -d '=' -f2-)"
|
|
100
|
+
# Read domain safely — quote all expansions, take first match only
|
|
101
|
+
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | head -1 | cut -d '=' -f2-)"
|
|
102
102
|
|
|
103
103
|
# Reject empty
|
|
104
104
|
if [ -z "$JIRA_DOMAIN" ]; then
|
|
@@ -106,9 +106,9 @@ if [ -z "$JIRA_DOMAIN" ]; then
|
|
|
106
106
|
exit 1
|
|
107
107
|
fi
|
|
108
108
|
|
|
109
|
-
# Must be a valid hostname
|
|
110
|
-
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9
|
|
111
|
-
echo "Error: JIRA_DOMAIN
|
|
109
|
+
# Must be a valid hostname — each label: alphanumeric, hyphens allowed mid-label, no consecutive dots
|
|
110
|
+
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$ ]]; then
|
|
111
|
+
echo "Error: JIRA_DOMAIN is not a valid hostname"
|
|
112
112
|
exit 1
|
|
113
113
|
fi
|
|
114
114
|
|
|
@@ -119,8 +119,8 @@ if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9-]+\.atlassian\.net$ ]]; then
|
|
|
119
119
|
# Require explicit user confirmation for non-standard domains
|
|
120
120
|
fi
|
|
121
121
|
|
|
122
|
-
# Reject IP addresses (
|
|
123
|
-
if [[ "$JIRA_DOMAIN" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
|
122
|
+
# Reject IP addresses — IPv4, IPv6 brackets, hex-encoded (SSRF prevention)
|
|
123
|
+
if [[ "$JIRA_DOMAIN" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]] || [[ "$JIRA_DOMAIN" =~ ^\[.*\]$ ]] || [[ "$JIRA_DOMAIN" =~ ^0x ]]; then
|
|
124
124
|
echo "Error: IP addresses not allowed — use a hostname"
|
|
125
125
|
exit 1
|
|
126
126
|
fi
|
|
@@ -132,61 +132,11 @@ if [[ "$JIRA_DOMAIN" =~ ^(localhost|127\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\
|
|
|
132
132
|
fi
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
### Step 5:
|
|
135
|
+
### Step 5: Credential Loading and API Calls
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
# Load credentials from .env (never display values)
|
|
139
|
-
JIRA_API_TOKEN="$(grep '^JIRA_API_TOKEN=' .env | cut -d '=' -f2-)"
|
|
140
|
-
JIRA_EMAIL="$(grep '^JIRA_EMAIL=' .env | cut -d '=' -f2-)"
|
|
141
|
-
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | cut -d '=' -f2-)"
|
|
142
|
-
|
|
143
|
-
# Create Basic Auth header (JIRA uses email:token)
|
|
144
|
-
AUTH="$(printf '%s:%s' "$JIRA_EMAIL" "$JIRA_API_TOKEN" | base64)"
|
|
145
|
-
|
|
146
|
-
# HTTPS only — never allow plain HTTP
|
|
147
|
-
# All variables double-quoted to prevent word splitting
|
|
148
|
-
curl -s -f \
|
|
149
|
-
-H "Authorization: Basic $AUTH" \
|
|
150
|
-
-H "Content-Type: application/json" \
|
|
151
|
-
"https://${JIRA_DOMAIN}/rest/api/3/myself" \
|
|
152
|
-
|| { echo "JIRA API connection failed"; exit 1; }
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Step 6: Never Log Secrets
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
# NEVER echo token values, auth headers, or base64-encoded credentials
|
|
159
|
-
# Only confirm presence:
|
|
160
|
-
echo "JIRA connection: domain=${JIRA_DOMAIN}, email present=yes, token present=yes"
|
|
161
|
-
```
|
|
137
|
+
This skill does NOT execute API calls directly (no Bash tool). Credential loading, authentication, and API operations are handled by the `jira-mapper` skill — see its **Security Rules** section for the hardened patterns (domain validation, HTTPS enforcement, SSRF prevention, variable quoting).
|
|
162
138
|
|
|
163
|
-
### Step
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Store HTTP status code from curl
|
|
167
|
-
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
168
|
-
-H "Authorization: Basic $AUTH" \
|
|
169
|
-
-H "Content-Type: application/json" \
|
|
170
|
-
"https://${JIRA_DOMAIN}/rest/api/3/myself")
|
|
171
|
-
|
|
172
|
-
case "$HTTP_STATUS" in
|
|
173
|
-
200) echo "JIRA authentication successful" ;;
|
|
174
|
-
401)
|
|
175
|
-
echo "JIRA credentials invalid (HTTP 401)"
|
|
176
|
-
echo "Check: API token may be expired or email incorrect"
|
|
177
|
-
echo "Manage tokens: https://id.atlassian.com/manage-profile/security/api-tokens"
|
|
178
|
-
;;
|
|
179
|
-
403)
|
|
180
|
-
echo "JIRA permission denied (HTTP 403)"
|
|
181
|
-
echo "Required permissions: Browse projects, Create issues, Edit issues"
|
|
182
|
-
;;
|
|
183
|
-
*)
|
|
184
|
-
echo "JIRA API error (HTTP $HTTP_STATUS)"
|
|
185
|
-
;;
|
|
186
|
-
esac
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Step 8: Production Recommendations
|
|
139
|
+
### Step 6: Production Recommendations
|
|
190
140
|
|
|
191
141
|
**For production deployments, use OAuth 2.0** instead of API tokens:
|
|
192
142
|
|
|
@@ -217,14 +167,14 @@ JIRA and Confluence are both Atlassian products and often used together. This sk
|
|
|
217
167
|
|
|
218
168
|
### Confluence Credentials
|
|
219
169
|
|
|
220
|
-
Same authentication
|
|
170
|
+
Same authentication and security rules as JIRA — user configures `.env`, skill only validates presence. Same domain validation applies (must be `<subdomain>.atlassian.net`, HTTPS only, no IPs).
|
|
221
171
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
CONFLUENCE_API_TOKEN
|
|
225
|
-
CONFLUENCE_EMAIL
|
|
226
|
-
CONFLUENCE_DOMAIN
|
|
227
|
-
CONFLUENCE_SPACE_KEY
|
|
172
|
+
Required `.env` keys (configured by the user, NOT by this skill):
|
|
173
|
+
```
|
|
174
|
+
CONFLUENCE_API_TOKEN=<your-token> # Same as JIRA API token
|
|
175
|
+
CONFLUENCE_EMAIL=<your-email>
|
|
176
|
+
CONFLUENCE_DOMAIN=<your-company>.atlassian.net
|
|
177
|
+
CONFLUENCE_SPACE_KEY=<space-key>
|
|
228
178
|
```
|
|
229
179
|
|
|
230
180
|
### Key Confluence Operations
|